home *** CD-ROM | disk | FTP | other *** search
/ Magazyn Exec 5 / CD_Magazyn_EXEC_nr_5.iso / eXec / Krotkie opisy / Programy / XADMaster / xad_CAB.lha / CAB.c < prev    next >
C/C++ Source or Header  |  2000-11-12  |  77KB  |  2,291 lines

  1. /* CAB -- an XAD client for extracting Microsoft Cabinet files
  2.  * (C) 2000 Stuart Caie <kyzer@4u.net>
  3.  *
  4.  * This program is free software; you can redistribute it and/or modify
  5.  * it under the terms of the GNU General Public License as published by
  6.  * the Free Software Foundation; either version 2 of the License, or
  7.  * (at your option) any later version.
  8.  *
  9.  * This program is distributed in the hope that it will be useful,
  10.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.  * GNU General Public License for more details.
  13.  *
  14.  * You should have received a copy of the GNU General Public License
  15.  * along with this program; if not, write to the Free Software
  16.  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17.  */
  18.  
  19. /* Credits:
  20.  * The CAB format, and MSZIP/LZX formats are described in the documents
  21.  * CABFMT.DOC, LZXFMT.DOC and MSZIPFMT.DOC in the CAB SDK, which is
  22.  * (C) 1997 Microsoft Corporation.
  23.  *
  24.  * MSZIP is a modification of the inflate and deflate methods created by
  25.  * Phil Katz. LZX was created by Johnathan Forbes and Tomi Poutanen.
  26.  *
  27.  * The MSZIP part of this client was written for me by Dirk Stöcker, who
  28.  * based it on code from InfoZip's free UnZip utility. Dirk also provided
  29.  * extensive testing materials, feedback and moral support (oh - and he
  30.  * created the XAD system :). I took the fast Huffman table builder from
  31.  * David Tritscher's unlzx (no relation :) and adapted to my needs.
  32.  */
  33.  
  34. /* CAB has pretty much everything - multivolume archives, merged file data,
  35.  * and multiple compression formats. 'Folders' store compressed data, and
  36.  * may span several cabinets. 'Files' live as data inside a folder when
  37.  * uncompressed. EOR checksums are used instead of CRCs. Four compression
  38.  * formats are known - NONE, MSZIP, QUANTUM and LZX. NONE is obviously
  39.  * uncompressed data. MSZIP is simply PKZIP's deflate/inflate algorithims
  40.  * with 'CK' as a signature instead of 'PK'. QUANTUM is a complete unknown,
  41.  * and isn't implemented in this client. LZX is a much loved LZH based
  42.  * archiver in the Amiga world, the algorithim taken (bought?) by Microsoft
  43.  * and tweaked for Intel code.
  44.  */
  45.  
  46. /* $VER: CAB.c 1.2 (12.11.2000) */
  47.  
  48. #include "SDI_compiler.h"
  49. #include "ConvertE.c"
  50. #include <exec/types.h>
  51. #include <exec/memory.h>
  52. #include <string.h>
  53. #include <libraries/xadmaster.h>
  54. #include <proto/xadmaster.h>
  55.  
  56. #ifdef DEBUG
  57. void KPrintF(char *fmt, ...);
  58. #define D(x) { KPrintF x ; }
  59. #else
  60. #define D(x)
  61. #endif
  62.  
  63. #define CABSTATE struct CABstate *cabstate
  64. #define XADBASE  REG(a6, struct xadMasterBase *xadMasterBase)
  65. #define CAB(x)   (cabstate->x)
  66. #define ZIP(x)   (cabstate->arcstate.zip.x)
  67. #define QTM(x)   (cabstate->arcstate.qtm.x)
  68. #define LZX(x)   (cabstate->arcstate.lzx.x)
  69.  
  70. #define CABFILEFOL(fi) ((struct CABfolder *)(fi)->xfi_PrivateInfo)
  71.  
  72. /* requires UBYTE buf[] */
  73. #define GETLONG(n) EndGetI32(&buf[n])
  74. #define GETWORD(n) EndGetI16(&buf[n])
  75. #define GETBYTE(n) buf[n]
  76.  
  77. #ifndef XADMASTERFILE
  78. #define CAB_Client        FirstClient
  79. #define NEXTCLIENT        0
  80. const UBYTE version[] = "$VER: CAB 1.2 (12.11.2000)";
  81. #endif
  82. #define CAB_VERSION        1
  83. #define CAB_REVISION        2
  84.  
  85. /* work-doing macros */
  86.  
  87. /* required: label exit_handler; struct xadArchiveInfo *ai; LONG err; */
  88.  
  89. #define SKIP(offset) if ((err = xadHookAccess(XADAC_INPUTSEEK, \
  90.   (ULONG)(offset), NULL, ai))) goto exit_handler
  91. #define SEEK(offset) SKIP((offset) - ai->xai_InPos)
  92.  
  93. #define READ(buffer,length) if ((err = xadHookAccess(XADAC_READ, \
  94.   (ULONG)(length), (APTR)(buffer), ai))) goto exit_handler
  95. #define WRITE(buffer,length) if ((err = xadHookAccess(XADAC_WRITE, \
  96.   (ULONG)(length), (APTR)(buffer), ai))) goto exit_handler
  97.  
  98. #define ERROR(error) { \
  99.   D(("CAB: error " #error " line %ld\n", __LINE__)) \
  100.   err = XADERR_##error; goto exit_handler; \
  101. }
  102. #define TAINT(reason) { \
  103.   ai->xai_Flags |= XADAIF_FILECORRUPT; \
  104.   D(("CAB: TAINT - " reason "\n")) \
  105. }
  106.  
  107. #define ALLOC(t,v,l) \
  108.   if (!((v) = (t) xadAllocVec((l),MEMF_CLEAR))) ERROR(NOMEMORY)
  109. #define ALLOCOBJ(t,v,kind,tags) \
  110.   if (!((v) = (t) xadAllocObjectA((kind),(tags)))) ERROR(NOMEMORY)
  111. #define FREE(obj) xadFreeObjectA((obj),NULL)
  112.  
  113. /*--------------------------------------------------------------------------*/
  114. /* our archiver information / state */
  115.  
  116. /* MSZIP stuff */
  117.  
  118. #define ZIPWSIZE     0x8000  /* window size--must be a power of two, and at least 32K for zip's deflate method */
  119. #define ZIPLBITS    9    /* bits in base literal/length lookup table */
  120. #define ZIPDBITS    6    /* bits in base distance lookup table */
  121. #define ZIPBMAX        16      /* maximum bit length of any code (16 for explode) */
  122. #define ZIPN_MAX    288     /* maximum number of codes in any set */
  123.  
  124. struct Ziphuft {
  125.   UBYTE e;                /* number of extra bits or operation */
  126.   UBYTE b;                /* number of bits in this code or subcode */
  127.   union {
  128.     UWORD n;              /* literal, length base, or distance base */
  129.     struct Ziphuft *t;    /* pointer to next level of table */
  130.   } v;
  131. };
  132.  
  133. struct CABZIPstate {
  134.     ULONG window_posn;     /* current offset within the window        */
  135.  
  136.     ULONG bb;              /* bit buffer */
  137.     ULONG bk;              /* bits in bit buffer */
  138.     ULONG ll[288+32];       /* literal/length and distance code lengths */
  139.     ULONG c[ZIPBMAX+1];    /* bit length count table */
  140.     LONG  lx[ZIPBMAX+1];   /* memory for l[-1..ZIPBMAX-1] */
  141.     struct Ziphuft *u[ZIPBMAX];             /* table stack */
  142.     ULONG v[ZIPN_MAX];     /* values in order of bit length */
  143.     ULONG x[ZIPBMAX+1];    /* bit offsets, then code stack */
  144.  
  145.     UBYTE *inpos;
  146. };
  147.  
  148.  
  149. /* Quantum stuff - not supported yet */
  150. struct CABQTMstate {
  151.     UBYTE *window;         /* the actual decoding window              */
  152.     ULONG window_size;     /* window size (4Kb through 2Mb)           */
  153.     ULONG actual_size;     /* window size when it was first allocated */
  154.     UWORD comp_level;      /* level of compression                    */
  155. };
  156.  
  157.  
  158. /* LZX stuff */
  159.  
  160. /* some constants defined by the LZX specification */
  161. #define LZX_MIN_MATCH                (2)
  162. #define LZX_MAX_MATCH                (257)
  163. #define LZX_NUM_CHARS                (256)
  164. #define LZX_BLOCKTYPE_INVALID        (0)   /* also blocktypes 4-7 invalid */
  165. #define LZX_BLOCKTYPE_VERBATIM       (1)
  166. #define LZX_BLOCKTYPE_ALIGNED        (2)
  167. #define LZX_BLOCKTYPE_UNCOMPRESSED   (3)
  168. #define LZX_PRETREE_NUM_ELEMENTS     (20)
  169. #define LZX_ALIGNED_NUM_ELEMENTS     (8)   /* aligned offset tree #elements */
  170. #define LZX_NUM_PRIMARY_LENGTHS      (7)   /* this one missing from spec! */
  171. #define LZX_NUM_SECONDARY_LENGTHS    (249) /* length tree #elements */
  172.  
  173.  
  174. /* LZX huffman defines: tweak tablebits as desired */
  175. #define LZX_PRETREE_MAXSYMBOLS  (LZX_PRETREE_NUM_ELEMENTS)
  176. #define LZX_PRETREE_TABLEBITS   (6)
  177. #define LZX_MAINTREE_MAXSYMBOLS (LZX_NUM_CHARS + 50*8)
  178. #define LZX_MAINTREE_TABLEBITS  (12)
  179. #define LZX_LENGTH_MAXSYMBOLS   (LZX_NUM_SECONDARY_LENGTHS+1)
  180. #define LZX_LENGTH_TABLEBITS    (12)
  181. #define LZX_ALIGNED_MAXSYMBOLS  (LZX_ALIGNED_NUM_ELEMENTS)
  182. #define LZX_ALIGNED_TABLEBITS   (7)
  183.  
  184. #define LZX_LENTABLE_SAFETY (64) /* we allow length table decoding overruns */
  185.  
  186. #define LZX_DECLARE_TABLE(tbl) \
  187.   UWORD tbl##_table[(1<<LZX_##tbl##_TABLEBITS) + (LZX_##tbl##_MAXSYMBOLS<<1)];\
  188.   UBYTE tbl##_len  [LZX_##tbl##_MAXSYMBOLS + LZX_LENTABLE_SAFETY]
  189.  
  190.  
  191. struct CABLZXstate {
  192.     UBYTE *window;         /* the actual decoding window              */
  193.     ULONG window_size;     /* window size (32Kb through 2Mb)          */
  194.     ULONG actual_size;     /* window size when it was first allocated */
  195.     ULONG window_posn;     /* current offset within the window        */
  196.     ULONG R0, R1, R2;      /* for the LRU offset system               */
  197.     UWORD main_elements;   /* number of main tree elements            */
  198.     BOOL  header_read;     /* have we started decoding at all yet?    */
  199.     UWORD block_type;      /* type of this block                      */
  200.     ULONG block_length;    /* uncompressed length of this block       */
  201.     ULONG block_remaining; /* uncompressed bytes still left to decode */
  202.     ULONG frames_read;     /* the number of CFDATA blocks processed   */
  203.     LONG  intel_filesize;  /* magic header value used for transform   */
  204.     LONG  intel_curpos;    /* current offset in transform space       */
  205.     BOOL  intel_started;   /* have we seen any translatable data yet? */
  206.  
  207.     LZX_DECLARE_TABLE(PRETREE);
  208.     LZX_DECLARE_TABLE(MAINTREE);
  209.     LZX_DECLARE_TABLE(LENGTH);
  210.     LZX_DECLARE_TABLE(ALIGNED);
  211. };
  212.  
  213.  
  214.  
  215. /*--------------------------------------------------------------------------*/
  216. /* CAB structures */
  217.  
  218. #define CFHEAD_SIGNATURE (('M') | ('S'<<8) | ('C'<<16) | ('F'<<24)) /*intel!*/
  219.  
  220. #define cfhead_Signature         (0x00)
  221. #define cfhead_Reserved1         (0x04)
  222. #define cfhead_CabinetSize       (0x08)
  223. #define cfhead_Reserved2         (0x0C)
  224. #define cfhead_FileOffset        (0x10)
  225. #define cfhead_Reserved3         (0x14)
  226. #define cfhead_MinorVersion      (0x18)
  227. #define cfhead_MajorVersion      (0x19)
  228. #define cfhead_NumFolders        (0x1A)
  229. #define cfhead_NumFiles          (0x1C)
  230. #define cfhead_Flags             (0x1E)
  231. #define cfhead_SetID             (0x20)
  232. #define cfhead_CabinetIndex      (0x22)
  233. #define cfhead_SIZEOF            (0x24)
  234. #define cfheadext_HeaderReserved (0x00)
  235. #define cfheadext_FolderReserved (0x02)
  236. #define cfheadext_DataReserved   (0x03)
  237. #define cfheadext_SIZEOF         (0x04)
  238. /* cfhead_ReservedArea (== HeaderReserved bytes) */
  239. /* cfhead_PrevCabFile (null terminated string)   */
  240. /* cfhead_PrevCabName (null terminated string)   */
  241. /* cfhead_NextCabFile (null terminated string)   */
  242. /* cfhead_NextCabName (null terminated string)   */
  243.  
  244. #define cffold_DataOffset        (0x00)
  245. #define cffold_NumBlocks         (0x04)
  246. #define cffold_CompType          (0x06)
  247. #define cffold_SIZEOF            (0x08)
  248. /* cffold_ReservedArea (== FolderReserved bytes) */
  249.  
  250. #define cffile_UncompressedSize  (0x00)
  251. #define cffile_FolderOffset      (0x04)
  252. #define cffile_FolderIndex       (0x08)
  253. #define cffile_Date              (0x0A)
  254. #define cffile_Time              (0x0C)
  255. #define cffile_Attribs           (0x0E)
  256. #define cffile_SIZEOF            (0x10)
  257. /* cffile_FileName (null terminated string)      */
  258.  
  259. #define cfdata_CheckSum          (0x00) /* cksum of header/reserved/data */
  260. #define cfdata_CompressedSize    (0x04) /* compressed size of block */
  261. #define cfdata_UncompressedSize  (0x06) /* uncompressed size of block */
  262. #define cfdata_SIZEOF            (0x08)
  263. /* cfdata_ReservedArea (== DataReserved bytes)   */
  264.  
  265. /* flags and values */
  266.  
  267. #define cffoldCOMPTYPE_MASK    (0x000f)
  268. #define cffoldCOMPTYPE_NONE    (0x0000)
  269. #define cffoldCOMPTYPE_MSZIP   (0x0001)
  270. #define cffoldCOMPTYPE_QUANTUM (0x0002)
  271. #define cffoldCOMPTYPE_LZX     (0x0003)
  272.  
  273. #define cfheadPREV_CABINET       (0x0001)
  274. #define cfheadNEXT_CABINET       (0x0002)
  275. #define cfheadRESERVE_PRESENT    (0x0004)
  276.  
  277. #define cffileCONTINUED_FROM_PREV      (0xFFFD)
  278. #define cffileCONTINUED_TO_NEXT        (0xFFFE)
  279. #define cffileCONTINUED_PREV_AND_NEXT  (0xFFFF)
  280. #define cffileUTFNAME (0x80)
  281.  
  282. #define CAB_NAMEMAX 512   /* maximum length of a single path/filename */
  283.  
  284. /* CAB data blocks are <= 32768 bytes in uncompressed form. Uncompressed
  285.  * blocks have zero growth. MSZIP guarantees that it won't grow above
  286.  * uncompressed size by more than 12 bytes. LZX guarantees it won't grow
  287.  * more than 6144 bytes.
  288.  */
  289. #define CAB_BLOCKMAX (32768)
  290. #define CAB_INPUTMAX (CAB_BLOCKMAX+6144)
  291.  
  292. /* maximum number of split blocks in any one folder */
  293. #define CAB_SPLITMAX (10)
  294.  
  295. struct CABfolder {
  296.   struct CABfolder *next;
  297.  
  298.   ULONG offsets[CAB_SPLITMAX];  /* offset of first/split data blocks  */
  299.   UBYTE data_res[CAB_SPLITMAX]; /* bytes reserved in block headers    */
  300.   ULONG comp_size;      /* number of compressed bytes in this part    */
  301.   UWORD comp_type;      /* compression format and window size         */
  302.   UWORD num_splits;     /* number of split blocks                     */
  303.   struct xadFileInfo *contfile; /* is this folder continuable?        */
  304. };
  305.  
  306. struct CABstate {
  307.   struct xadMasterBase *xad; /* XAD library base                      */
  308.   struct xadArchiveInfo *ai; /* archive we're extracting from         */
  309.   struct CABfolder *folders; /* linked list of all folders            */
  310.   struct CABfolder *current; /* current folder we're extracting from  */
  311.   ULONG offset;              /* uncompressed offset within folder     */
  312.   UBYTE *outpos;             /* (high level) start of data to use up  */
  313.   UWORD outlen;              /* (high level) amount of data to use up */
  314.   UBYTE split;               /* at which split in current folder?     */
  315.  
  316.   /* to speed up the arrival of an error message for trashed files */
  317.   struct CABfolder *lastfolder;
  318.   ULONG lastoffset;
  319.   LONG lasterror;
  320.  
  321.   /* the chosen compression type functions */
  322.   LONG (*decompress)(CABSTATE, int, int);
  323.   void (*free)(CABSTATE);
  324.  
  325.   union {
  326.     struct CABZIPstate zip;
  327.     struct CABQTMstate qtm;
  328.     struct CABLZXstate lzx;
  329.   } arcstate;
  330.  
  331.   UBYTE inbuf[CAB_INPUTMAX], outbuf[CAB_BLOCKMAX];
  332. };
  333.  
  334. /*--------------------------------------------------------------------------*/
  335. /* MSZIP decompressor */
  336.  
  337. /* This part was written by Dirk Stöcker, based on the InfoZip deflate code */
  338.  
  339. /* Tables for deflate from PKZIP's appnote.txt. */
  340. static const UBYTE Zipborder[] = /* Order of the bit length code lengths */
  341. { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
  342. static const UWORD Zipcplens[] = /* Copy lengths for literal codes 257..285 */
  343. { 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51,
  344.  59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
  345. static const UWORD Zipcplext[] = /* Extra bits for literal codes 257..285 */
  346. { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4,
  347.   4, 5, 5, 5, 5, 0, 99, 99}; /* 99==invalid */
  348. static const UWORD Zipcpdist[] = /* Copy offsets for distance codes 0..29 */
  349. { 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385,
  350. 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577};
  351. static const UWORD Zipcpdext[] = /* Extra bits for distance codes */
  352. { 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10,
  353. 10, 11, 11, 12, 12, 13, 13};
  354.  
  355. /* And'ing with Zipmask[n] masks the lower n bits */
  356. static const UWORD Zipmask[17] = {
  357.  0x0000, 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
  358.  0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
  359. };
  360.  
  361. #define ZIPNEEDBITS(n) {while(k<(n)){LONG c=*(ZIP(inpos)++);\
  362.     b|=((ULONG)c)<<k;k+=8;}}
  363. #define ZIPDUMPBITS(n) {b>>=(n);k-=(n);}
  364.  
  365. static LONG Ziphuft_free(CABSTATE, struct Ziphuft *t)
  366. {
  367.   struct xadMasterBase *xadMasterBase = CAB(xad);
  368.   register struct Ziphuft *p, *q;
  369.  
  370.   /* Go through linked list, freeing from the allocated (t[-1]) address. */
  371.   p = t;
  372.   while (p != (struct Ziphuft *)NULL)
  373.   {
  374.     q = (--p)->v.t;
  375.     xadFreeObjectA(p, 0);
  376.     p = q;
  377.   } 
  378.   return 0;
  379. }
  380.  
  381. static LONG Ziphuft_build(CABSTATE, ULONG *b, ULONG n, ULONG s, UWORD *d, UWORD *e, struct Ziphuft **t, LONG *m)
  382. {
  383.   ULONG a;                       /* counter for codes of length k */
  384.   ULONG el;                      /* length of EOB code (value 256) */
  385.   ULONG f;                       /* i repeats in table every f entries */
  386.   LONG g;                        /* maximum code length */
  387.   LONG h;                        /* table level */
  388.   register ULONG i;              /* counter, current code */
  389.   register ULONG j;              /* counter */
  390.   register LONG k;               /* number of bits in current code */
  391.   LONG *l;                   /* stack of bits per table */
  392.   register ULONG *p;             /* pointer into ZIP(c)[], ZIP(b)[], or ZIP(v)[] */
  393.   register struct Ziphuft *q;   /* points to current table */
  394.   struct Ziphuft r;             /* table entry for structure assignment */
  395.   register LONG w;              /* bits before this table == (l * h) */
  396.   ULONG *xp;                     /* pointer into x */
  397.   LONG y;                       /* number of dummy codes added */
  398.   ULONG z;                       /* number of entries in current table */
  399.   struct xadMasterBase *xadMasterBase = CAB(xad);
  400.  
  401.   l = ZIP(lx)+1;
  402.  
  403.   /* Generate counts for each bit length */
  404.   el = n > 256 ? b[256] : ZIPBMAX; /* set length of EOB code, if any */
  405.  
  406.   for(i = 0; i < ZIPBMAX+1; ++i)
  407.     ZIP(c)[i] = 0;
  408.   p = b;  i = n;
  409.   do
  410.   {
  411.     ZIP(c)[*p]++; p++;               /* assume all entries <= ZIPBMAX */
  412.   } while (--i);
  413.   if (ZIP(c)[0] == n)                /* null input--all zero length codes */
  414.   {
  415.     *t = (struct Ziphuft *)NULL;
  416.     *m = 0;
  417.     return 0;
  418.   }
  419.  
  420.   /* Find minimum and maximum length, bound *m by those */
  421.   for (j = 1; j <= ZIPBMAX; j++)
  422.     if (ZIP(c)[j])
  423.       break;
  424.   k = j;                        /* minimum code length */
  425.   if ((ULONG)*m < j)
  426.     *m = j;
  427.   for (i = ZIPBMAX; i; i--)
  428.     if (ZIP(c)[i])
  429.       break;
  430.   g = i;                        /* maximum code length */
  431.   if ((ULONG)*m > i)
  432.     *m = i;
  433.  
  434.   /* Adjust last length count to fill out codes, if needed */
  435.   for (y = 1 << j; j < i; j++, y <<= 1)
  436.     if ((y -= ZIP(c)[j]) < 0)
  437.       return 2;                 /* bad input: more codes than bits */
  438.   if ((y -= ZIP(c)[i]) < 0)
  439.     return 2;
  440.   ZIP(c)[i] += y;
  441.  
  442.   /* Generate starting offsets LONGo the value table for each length */
  443.   ZIP(x)[1] = j = 0;
  444.   p = ZIP(c) + 1;  xp = ZIP(x) + 2;
  445.   while (--i)
  446.   {                 /* note that i == g from above */
  447.     *xp++ = (j += *p++);
  448.   }
  449.  
  450.   /* Make a table of values in order of bit lengths */
  451.   p = b;  i = 0;
  452.   do{
  453.     if ((j = *p++) != 0)
  454.       ZIP(v)[ZIP(x)[j]++] = i;
  455.   } while (++i < n);
  456.  
  457.  
  458.   /* Generate the Huffman codes and for each, make the table entries */
  459.   ZIP(x)[0] = i = 0;                 /* first Huffman code is zero */
  460.   p = ZIP(v);                        /* grab values in bit order */
  461.   h = -1;                       /* no tables yet--level -1 */
  462.   w = l[-1] = 0;                /* no bits decoded yet */
  463.   ZIP(u)[0] = (struct Ziphuft *)NULL;   /* just to keep compilers happy */
  464.   q = (struct Ziphuft *)NULL;      /* ditto */
  465.   z = 0;                        /* ditto */
  466.  
  467.   /* go through the bit lengths (k already is bits in shortest code) */
  468.   for (; k <= g; k++)
  469.   {
  470.     a = ZIP(c)[k];
  471.     while (a--)
  472.     {
  473.       /* here i is the Huffman code of length k bits for value *p */
  474.       /* make tables up to required level */
  475.       while (k > w + l[h])
  476.       {
  477.         w += l[h++];            /* add bits already decoded */
  478.  
  479.         /* compute minimum size table less than or equal to *m bits */
  480.         z = (z = g - w) > (ULONG)*m ? *m : z;        /* upper limit */
  481.         if ((f = 1 << (j = k - w)) > a + 1)     /* try a k-w bit table */
  482.         {                       /* too few codes for k-w bit table */
  483.           f -= a + 1;           /* deduct codes from patterns left */
  484.           xp = ZIP(c) + k;
  485.           while (++j < z)       /* try smaller tables up to z bits */
  486.           {
  487.             if ((f <<= 1) <= *++xp)
  488.               break;            /* enough codes to use up j bits */
  489.             f -= *xp;           /* else deduct codes from patterns */
  490.           }
  491.         }
  492.         if ((ULONG)w + j > el && (ULONG)w < el)
  493.           j = el - w;           /* make EOB code end at table */
  494.         z = 1 << j;             /* table entries for j-bit table */
  495.         l[h] = j;               /* set table size in stack */
  496.  
  497.         /* allocate and link in new table */
  498.         if (!(q = (struct Ziphuft *) xadAllocVec((z + 1)*sizeof(struct Ziphuft), MEMF_PUBLIC)))
  499.         {
  500.           if(h)
  501.             Ziphuft_free(cabstate, ZIP(u)[0]);
  502.           return 3;             /* not enough memory */
  503.         }
  504.         *t = q + 1;             /* link to list for Ziphuft_free() */
  505.         *(t = &(q->v.t)) = (struct Ziphuft *)NULL;
  506.         ZIP(u)[h] = ++q;             /* table starts after link */
  507.  
  508.         /* connect to last table, if there is one */
  509.         if (h)
  510.         {
  511.           ZIP(x)[h] = i;             /* save pattern for backing up */
  512.           r.b = (UBYTE)l[h-1];    /* bits to dump before this table */
  513.           r.e = (UBYTE)(16 + j);  /* bits in this table */
  514.           r.v.t = q;            /* pointer to this table */
  515.           j = (i & ((1 << w) - 1)) >> (w - l[h-1]);
  516.           ZIP(u)[h-1][j] = r;        /* connect to last table */
  517.         }
  518.       }
  519.  
  520.       /* set up table entry in r */
  521.       r.b = (UBYTE)(k - w);
  522.       if (p >= ZIP(v) + n)
  523.         r.e = 99;               /* out of values--invalid code */
  524.       else if (*p < s)
  525.       {
  526.         r.e = (UBYTE)(*p < 256 ? 16 : 15);    /* 256 is end-of-block code */
  527.         r.v.n = *p++;           /* simple code is just the value */
  528.       }
  529.       else
  530.       {
  531.         r.e = (UBYTE)e[*p - s];   /* non-simple--look up in lists */
  532.         r.v.n = d[*p++ - s];
  533.       }
  534.  
  535.       /* fill code-like entries with r */
  536.       f = 1 << (k - w);
  537.       for (j = i >> w; j < z; j += f)
  538.         q[j] = r;
  539.  
  540.       /* backwards increment the k-bit code i */
  541.       for (j = 1 << (k - 1); i & j; j >>= 1)
  542.         i ^= j;
  543.       i ^= j;
  544.  
  545.       /* backup over finished tables */
  546.       while ((i & ((1 << w) - 1)) != ZIP(x)[h])
  547.         w -= l[--h];            /* don't need to update q */
  548.     }
  549.   }
  550.  
  551.   /* return actual size of base table */
  552.   *m = l[0];
  553.  
  554.   /* Return true (1) if we were given an incomplete table */
  555.   return y != 0 && g != 1;
  556. }
  557.  
  558. static LONG Zipinflate_codes(CABSTATE, struct Ziphuft *tl, struct Ziphuft *td, LONG bl, LONG bd)
  559. {
  560.   register ULONG e;  /* table entry flag/number of extra bits */
  561.   ULONG n, d;        /* length and index for copy */
  562.   ULONG w;           /* current window position */
  563.   struct Ziphuft *t; /* pointer to table entry */
  564.   ULONG ml, md;      /* masks for bl and bd bits */
  565.   register ULONG b;  /* bit buffer */
  566.   register ULONG k;  /* number of bits in bit buffer */
  567.  
  568.   /* make local copies of globals */
  569.   b = ZIP(bb);                       /* initialize bit buffer */
  570.   k = ZIP(bk);
  571.   w = ZIP(window_posn);                       /* initialize window position */
  572.  
  573.   /* inflate the coded data */
  574.   ml = Zipmask[bl];               /* precompute masks for speed */
  575.   md = Zipmask[bd];
  576.  
  577.   for(;;)
  578.   {
  579.     ZIPNEEDBITS((ULONG)bl)
  580.     if((e = (t = tl + ((ULONG)b & ml))->e) > 16)
  581.       do
  582.       {
  583.         if (e == 99)
  584.           return 1;
  585.         ZIPDUMPBITS(t->b)
  586.         e -= 16;
  587.         ZIPNEEDBITS(e)
  588.       } while ((e = (t = t->v.t + ((ULONG)b & Zipmask[e]))->e) > 16);
  589.     ZIPDUMPBITS(t->b)
  590.     if (e == 16)                /* then it's a literal */
  591.       CAB(outbuf)[w++] = (UBYTE)t->v.n;
  592.     else                        /* it's an EOB or a length */
  593.     {
  594.       /* exit if end of block */
  595.       if(e == 15)
  596.         break;
  597.  
  598.       /* get length of block to copy */
  599.       ZIPNEEDBITS(e)
  600.       n = t->v.n + ((ULONG)b & Zipmask[e]);
  601.       ZIPDUMPBITS(e);
  602.  
  603.       /* decode distance of block to copy */
  604.       ZIPNEEDBITS((ULONG)bd)
  605.       if ((e = (t = td + ((ULONG)b & md))->e) > 16)
  606.         do {
  607.           if (e == 99)
  608.             return 1;
  609.           ZIPDUMPBITS(t->b)
  610.           e -= 16;
  611.           ZIPNEEDBITS(e)
  612.         } while ((e = (t = t->v.t + ((ULONG)b & Zipmask[e]))->e) > 16);
  613.       ZIPDUMPBITS(t->b)
  614.       ZIPNEEDBITS(e)
  615.       d = w - t->v.n - ((ULONG)b & Zipmask[e]);
  616.       ZIPDUMPBITS(e)
  617.       do
  618.       {
  619.         n -= (e = (e = ZIPWSIZE - ((d &= ZIPWSIZE-1) > w ? d : w)) > n ? n : e);
  620.         do
  621.         {
  622.           CAB(outbuf)[w++] = CAB(outbuf)[d++];
  623.         } while (--e);
  624.       } while (n);
  625.     }
  626.   }
  627.  
  628.   /* restore the globals from the locals */
  629.   ZIP(window_posn) = w;                       /* restore global window pointer */
  630.   ZIP(bb) = b;                       /* restore global bit buffer */
  631.   ZIP(bk) = k;
  632.  
  633.   /* done */
  634.   return 0;
  635. }
  636.  
  637. static LONG Zipinflate_stored(CABSTATE) /* "decompress" an inflated type 0 (stored) block. */
  638. {
  639.   ULONG n;           /* number of bytes in block */
  640.   ULONG w;           /* current window position */
  641.   register ULONG b;  /* bit buffer */
  642.   register ULONG k;  /* number of bits in bit buffer */
  643.  
  644.   /* make local copies of globals */
  645.   b = ZIP(bb);                       /* initialize bit buffer */
  646.   k = ZIP(bk);
  647.   w = ZIP(window_posn);                       /* initialize window position */
  648.  
  649.   /* go to byte boundary */
  650.   n = k & 7;
  651.   ZIPDUMPBITS(n);
  652.  
  653.   /* get the length and its complement */
  654.   ZIPNEEDBITS(16)
  655.   n = ((ULONG)b & 0xffff);
  656.   ZIPDUMPBITS(16)
  657.   ZIPNEEDBITS(16)
  658.   if (n != (ULONG)((~b) & 0xffff))
  659.     return 1;                   /* error in compressed data */
  660.   ZIPDUMPBITS(16)
  661.  
  662.   /* read and output the compressed data */
  663.   while(n--)
  664.   {
  665.     ZIPNEEDBITS(8)
  666.     CAB(outbuf)[w++] = (UBYTE)b;
  667.     ZIPDUMPBITS(8)
  668.   }
  669.  
  670.   /* restore the globals from the locals */
  671.   ZIP(window_posn) = w;                       /* restore global window pointer */
  672.   ZIP(bb) = b;                       /* restore global bit buffer */
  673.   ZIP(bk) = k;
  674.   return 0;
  675. }
  676.  
  677. static LONG Zipinflate_fixed(CABSTATE)
  678. {
  679.   struct Ziphuft *fixed_tl;
  680.   struct Ziphuft *fixed_td;
  681.   LONG fixed_bl, fixed_bd;
  682.   LONG i;                /* temporary variable */
  683.   ULONG *l;
  684.  
  685.   l = ZIP(ll);
  686.  
  687.   /* literal table */
  688.   for(i = 0; i < 144; i++)
  689.     l[i] = 8;
  690.   for(; i < 256; i++)
  691.     l[i] = 9;
  692.   for(; i < 280; i++)
  693.     l[i] = 7;
  694.   for(; i < 288; i++)          /* make a complete, but wrong code set */
  695.     l[i] = 8;
  696.   fixed_bl = 7;
  697.   if((i = Ziphuft_build(cabstate, l, 288, 257, (UWORD *) Zipcplens, (UWORD *) Zipcplext, &fixed_tl, &fixed_bl)))
  698.     return i;
  699.  
  700.   /* distance table */
  701.   for(i = 0; i < 30; i++)      /* make an incomplete code set */
  702.     l[i] = 5;
  703.   fixed_bd = 5;
  704.   if((i = Ziphuft_build(cabstate, l, 30, 0, (UWORD *) Zipcpdist, (UWORD *) Zipcpdext, &fixed_td, &fixed_bd)) > 1)
  705.   {
  706.     Ziphuft_free(cabstate, fixed_tl);
  707.     return i;
  708.   }
  709.  
  710.   /* decompress until an end-of-block code */
  711.   i = Zipinflate_codes(cabstate, fixed_tl, fixed_td, fixed_bl, fixed_bd);
  712.  
  713.   Ziphuft_free(cabstate, fixed_td);
  714.   Ziphuft_free(cabstate, fixed_tl);
  715.   return i;
  716. }
  717.  
  718. static LONG Zipinflate_dynamic(CABSTATE) /* decompress an inflated type 2 (dynamic Huffman codes) block. */
  719. {
  720.   LONG i;              /* temporary variables */
  721.   ULONG j;
  722.   ULONG *ll;
  723.   ULONG l;               /* last length */
  724.   ULONG m;               /* mask for bit lengths table */
  725.   ULONG n;               /* number of lengths to get */
  726.   struct Ziphuft *tl;      /* literal/length code table */
  727.   struct Ziphuft *td;      /* distance code table */
  728.   LONG bl;              /* lookup bits for tl */
  729.   LONG bd;              /* lookup bits for td */
  730.   ULONG nb;              /* number of bit length codes */
  731.   ULONG nl;              /* number of literal/length codes */
  732.   ULONG nd;              /* number of distance codes */
  733.   register ULONG b;     /* bit buffer */
  734.   register ULONG k;    /* number of bits in bit buffer */
  735.  
  736.   /* make local bit buffer */
  737.   b = ZIP(bb);
  738.   k = ZIP(bk);
  739.   ll = ZIP(ll);
  740.  
  741.   /* read in table lengths */
  742.   ZIPNEEDBITS(5)
  743.   nl = 257 + ((ULONG)b & 0x1f);      /* number of literal/length codes */
  744.   ZIPDUMPBITS(5)
  745.   ZIPNEEDBITS(5)
  746.   nd = 1 + ((ULONG)b & 0x1f);        /* number of distance codes */
  747.   ZIPDUMPBITS(5)
  748.   ZIPNEEDBITS(4)
  749.   nb = 4 + ((ULONG)b & 0xf);         /* number of bit length codes */
  750.   ZIPDUMPBITS(4)
  751.   if(nl > 288 || nd > 32)
  752.     return 1;                   /* bad lengths */
  753.  
  754.   /* read in bit-length-code lengths */
  755.   for(j = 0; j < nb; j++)
  756.   {
  757.     ZIPNEEDBITS(3)
  758.     ll[Zipborder[j]] = (ULONG)b & 7;
  759.     ZIPDUMPBITS(3)
  760.   }
  761.   for(; j < 19; j++)
  762.     ll[Zipborder[j]] = 0;
  763.  
  764.   /* build decoding table for trees--single level, 7 bit lookup */
  765.   bl = 7;
  766.   if((i = Ziphuft_build(cabstate, ll, 19, 19, NULL, NULL, &tl, &bl)) != 0)
  767.   {
  768.     if(i == 1)
  769.       Ziphuft_free(cabstate, tl);
  770.     return i;                   /* incomplete code set */
  771.   }
  772.  
  773.   /* read in literal and distance code lengths */
  774.   n = nl + nd;
  775.   m = Zipmask[bl];
  776.   i = l = 0;
  777.   while((ULONG)i < n)
  778.   {
  779.     ZIPNEEDBITS((ULONG)bl)
  780.     j = (td = tl + ((ULONG)b & m))->b;
  781.     ZIPDUMPBITS(j)
  782.     j = td->v.n;
  783.     if (j < 16)                 /* length of code in bits (0..15) */
  784.       ll[i++] = l = j;          /* save last length in l */
  785.     else if (j == 16)           /* repeat last length 3 to 6 times */
  786.     {
  787.       ZIPNEEDBITS(2)
  788.       j = 3 + ((ULONG)b & 3);
  789.       ZIPDUMPBITS(2)
  790.       if((ULONG)i + j > n)
  791.         return 1;
  792.       while (j--)
  793.         ll[i++] = l;
  794.     }
  795.     else if (j == 17)           /* 3 to 10 zero length codes */
  796.     {
  797.       ZIPNEEDBITS(3)
  798.       j = 3 + ((ULONG)b & 7);
  799.       ZIPDUMPBITS(3)
  800.       if ((ULONG)i + j > n)
  801.         return 1;
  802.       while (j--)
  803.         ll[i++] = 0;
  804.       l = 0;
  805.     }
  806.     else                        /* j == 18: 11 to 138 zero length codes */
  807.     {
  808.       ZIPNEEDBITS(7)
  809.       j = 11 + ((ULONG)b & 0x7f);
  810.       ZIPDUMPBITS(7)
  811.       if ((ULONG)i + j > n)
  812.         return 1;
  813.       while (j--)
  814.         ll[i++] = 0;
  815.       l = 0;
  816.     }
  817.   }
  818.  
  819.   /* free decoding table for trees */
  820.   Ziphuft_free(cabstate, tl);
  821.  
  822.   /* restore the global bit buffer */
  823.   ZIP(bb) = b;
  824.   ZIP(bk) = k;
  825.  
  826.   /* build the decoding tables for literal/length and distance codes */
  827.   bl = ZIPLBITS;
  828.   if((i = Ziphuft_build(cabstate, ll, nl, 257, (UWORD *) Zipcplens, (UWORD *) Zipcplext, &tl, &bl)) != 0)
  829.   {
  830.     if(i == 1)
  831.       Ziphuft_free(cabstate, tl);
  832.     return i;                   /* incomplete code set */
  833.   }
  834.   bd = ZIPDBITS;
  835.   Ziphuft_build(cabstate, ll + nl, nd, 0, (UWORD *) Zipcpdist, (UWORD *) Zipcpdext, &td, &bd);
  836.  
  837.   /* decompress until an end-of-block code */
  838.   if(Zipinflate_codes(cabstate, tl, td, bl, bd))
  839.     return 1;
  840.  
  841.   /* free the decoding tables, return */
  842.   Ziphuft_free(cabstate, tl);
  843.   Ziphuft_free(cabstate, td);
  844.   return 0;
  845. }
  846.  
  847. static LONG Zipinflate_block(CABSTATE, LONG *e) /* e == last block flag */
  848. { /* decompress an inflated block */
  849.   ULONG t;               /* block type */
  850.   register ULONG b;     /* bit buffer */
  851.   register ULONG k;     /* number of bits in bit buffer */
  852.  
  853.   /* make local bit buffer */
  854.   b = ZIP(bb);
  855.   k = ZIP(bk);
  856.  
  857.   /* read in last block bit */
  858.   ZIPNEEDBITS(1)
  859.   *e = (LONG)b & 1;
  860.   ZIPDUMPBITS(1)
  861.  
  862.   /* read in block type */
  863.   ZIPNEEDBITS(2)
  864.   t = (ULONG)b & 3;
  865.   ZIPDUMPBITS(2)
  866.  
  867.   /* restore the global bit buffer */
  868.   ZIP(bb) = b;
  869.   ZIP(bk) = k;
  870.  
  871.   D(("ZIP: blocktype=%ld, last block=%ld\n", t, *e))
  872.  
  873.   /* inflate that block type */
  874.   if(t == 2)
  875.     return Zipinflate_dynamic(cabstate);
  876.   if(t == 0)
  877.     return Zipinflate_stored(cabstate);
  878.   if(t == 1)
  879.     return Zipinflate_fixed(cabstate);
  880.   /* bad block type */
  881.   return 2;
  882. }
  883.  
  884. LONG CAB_ZIPdecompress(CABSTATE, int inlen, int outlen)
  885. {
  886.   LONG e;               /* last block flag */
  887.  
  888.   D(("ZIP: outlen %ld\n", outlen))
  889.   ZIP(inpos) = CAB(inbuf);
  890.   ZIP(bb) = ZIP(bk) = ZIP(window_posn) = 0;
  891.   if(outlen > ZIPWSIZE)
  892.     return XADERR_DATAFORMAT;
  893.  
  894.   /* CK = Chris Kirmse, official Microsoft purloiner */
  895.   if(ZIP(inpos)[0] != 0x43 || ZIP(inpos)[1] != 0x4B)
  896.     return XADERR_ILLEGALDATA;
  897.   ZIP(inpos) += 2;
  898.  
  899.   do
  900.   {
  901.     if(Zipinflate_block(cabstate, &e))
  902.       return XADERR_ILLEGALDATA;
  903.   } while(!e);
  904.  
  905.   /* return success */
  906.   return XADERR_OK;
  907. }
  908.  
  909. /*--------------------------------------------------------------------------*/
  910. /* Quantum decompressor */
  911.  
  912. LONG CAB_QTMinit(CABSTATE, int level, int window) {
  913.   struct xadMasterBase *xadMasterBase = CAB(xad);
  914.   ULONG wndsize = 1 << window;
  915.  
  916.   /* Quantum supports window sizes of 2^10 (4Kb) through 2^21 (2Mb) */
  917.   /* if a previously allocated window is big enough, keep it     */
  918.   if (window < 10 || window > 21) return XADERR_DATAFORMAT;
  919.   if (QTM(actual_size) < wndsize) {
  920.     if (QTM(window)) FREE(QTM(window));
  921.     QTM(window) = NULL;
  922.   }
  923.   if (!QTM(window)) {
  924.     /* not using ALLOC() macro because we don't need to clear the window */
  925.     if (!(QTM(window) = xadAllocVec(wndsize, 0))) return XADERR_NOMEMORY;
  926.     QTM(actual_size) = wndsize;
  927.   }
  928.   QTM(window_size) = wndsize;
  929.   QTM(comp_level) = level;
  930.  
  931.   return XADERR_OK;
  932. }
  933.  
  934. void CAB_QTMfree(CABSTATE) {
  935.   struct xadMasterBase *xadMasterBase = CAB(xad);
  936.   if (QTM(window)) FREE(QTM(window));
  937.   QTM(window) = NULL;
  938. }
  939.  
  940.  
  941. LONG CAB_QTMdecompress(CABSTATE, int inlen, int outlen) {
  942.   return XADERR_DATAFORMAT;
  943. }
  944.  
  945. /*--------------------------------------------------------------------------*/
  946. /* LZX decompressor */
  947.  
  948. /* Microsoft's LZX document and their implementation of the
  949.  * com.ms.util.cab Java package do not concur.
  950.  * 
  951.  * Correlation between window size and number of position slots: In the
  952.  * LZX document, 1MB window = 40 slots, 2MB window = 42 slots. In the
  953.  * implementation, 1MB = 42 slots, 2MB = 50 slots. (The actual calculation
  954.  * is 'find the first slot whose position base is equal to or more than the
  955.  * required window size'). This would explain why other tables in the
  956.  * document refer to 50 slots rather than 42.
  957.  *
  958.  * The constant NUM_PRIMARY_LENGTHS used in the decompression pseudocode
  959.  * is not defined in the specification, although it could be derived from
  960.  * the section on encoding match lengths.
  961.  *
  962.  * The LZX document does not state the uncompressed block has an
  963.  * uncompressed length. Where does this length field come from, so we can
  964.  * know how large the block is? The implementation suggests that it's in
  965.  * the 24 bits proceeding the 3 blocktype bits, before the alignment
  966.  * padding.
  967.  *
  968.  * The LZX document states that aligned offset blocks have their aligned
  969.  * offset huffman tree AFTER the main and length tree. The implementation
  970.  * suggests that the aligned offset tree is BEFORE the main and length trees.
  971.  *
  972.  * The LZX document decoding algorithim states that, in an aligned offset
  973.  * block, if an extra_bits value is 1, 2 or 3, then that number of bits
  974.  * should be read and the result added to the match offset. This is correct
  975.  * for 1 and 2, but not 3 bits, where only an aligned symbol should be read.
  976.  */
  977.  
  978. /* LZX uses what it calls 'position slots' to represent match offsets.
  979.  * What this means is that a small 'position slot' number and a small
  980.  * offset from that slot are encoded instead of one large offset for
  981.  * every match.
  982.  * - position_base is an index to the position slot bases
  983.  * - extra_bits states how many bits of offset-from-base data is needed.
  984.  */
  985. static ULONG position_base[51];
  986. static UBYTE extra_bits[51];
  987.  
  988.  
  989. LONG CAB_LZXinit(CABSTATE, int window) {
  990.   struct xadMasterBase *xadMasterBase = CAB(xad);
  991.   int wndsize = 1 << window;
  992.   int i, j, posn_slots;
  993.  
  994.   D(("LZX: init wndsize=%ld\n", window))
  995.  
  996.   /* LZX supports window sizes of 2^15 (32Kb) through 2^21 (2Mb) */
  997.   /* if a previously allocated window is big enough, keep it     */
  998.   if (window < 15 || window > 21) return XADERR_DATAFORMAT;
  999.   if (LZX(actual_size) < wndsize) {
  1000.     if (LZX(window)) FREE(LZX(window));
  1001.     LZX(window) = NULL;
  1002.   }
  1003.   if (!LZX(window)) {
  1004.     /* not using ALLOC() macro because we don't need to clear the window */
  1005.     if (!(LZX(window) = xadAllocVec(wndsize, 0))) return XADERR_NOMEMORY;
  1006.     LZX(actual_size) = wndsize;
  1007.   }
  1008.   LZX(window_size) = wndsize;
  1009.  
  1010.   /* initialise static tables */
  1011.   for (i=0, j=0; i <= 50; i += 2) {
  1012.     extra_bits[i] = extra_bits[i+1] = j; /* 0,0,0,0,1,1,2,2,3,3... */
  1013.     if ((i != 0) && (j < 17)) j++; /* 0,0,1,2,3,4...15,16,17,17,17,17... */
  1014.   }
  1015.   for (i=0, j=0; i <= 50; i++) {
  1016.     position_base[i] = j; /* 0,1,2,3,4,6,8,12,16,24,32,... */
  1017.     j += 1 << extra_bits[i]; /* 1,1,1,1,2,2,4,4,8,8,16,16,32,32,... */
  1018.   }
  1019.  
  1020.   /* calculate required position slots */
  1021.        if (window == 20) posn_slots = 42;
  1022.   else if (window == 21) posn_slots = 50;
  1023.   else posn_slots = window << 1;
  1024.  
  1025.   /*posn_slots=i=0; while (i < wndsize) i += 1 << extra_bits[posn_slots++]; */
  1026.   
  1027.  
  1028.   LZX(R0)  =  LZX(R1)  = LZX(R2) = 1;
  1029.   LZX(main_elements)   = LZX_NUM_CHARS + (posn_slots << 3);
  1030.   LZX(header_read)     = 0;
  1031.   LZX(frames_read)     = 0;
  1032.   LZX(block_remaining) = 0;
  1033.   LZX(block_type)      = LZX_BLOCKTYPE_INVALID;
  1034.   LZX(intel_curpos)    = 0;
  1035.   LZX(intel_started)   = 0;
  1036.   LZX(window_posn)     = 0;
  1037.  
  1038.   /* initialise tables to 0 (because deltas will be applied to them) */
  1039.   for (i = 0; i < LZX_MAINTREE_MAXSYMBOLS; i++) LZX(MAINTREE_len)[i] = 0;
  1040.   for (i = 0; i < LZX_LENGTH_MAXSYMBOLS; i++)   LZX(LENGTH_len)[i]   = 0;
  1041.  
  1042.   return XADERR_OK;
  1043. }
  1044.  
  1045. void CAB_LZXfree(CABSTATE) {
  1046.   struct xadMasterBase *xadMasterBase = CAB(xad);
  1047.   if (LZX(window)) FREE(LZX(window));
  1048.   LZX(window) = NULL;
  1049. }
  1050.  
  1051.  
  1052.  
  1053. /* Bitstream reading macros:
  1054.  *
  1055.  * INIT_BITSTREAM    should be used first to set up the system
  1056.  * READ_BITS(var,n)  takes N bits from the buffer and puts them in var
  1057.  *
  1058.  * ENSURE_BITS(n)    ensures there are at least N bits in the bit buffer
  1059.  * PEEK_BITS(n)      extracts (without removing) N bits from the bit buffer
  1060.  * REMOVE_BITS(n)    removes N bits from the bit buffer
  1061.  *
  1062.  * These bit access routines work by using the area beyond the MSB and the
  1063.  * LSB as a free source of zeroes. This avoids having to mask any bits.
  1064.  * So we have to know the bit width of the bitbuffer variable. This is
  1065.  * sizeof(ULONG) * 8, also defined as ULONG_BITS
  1066.  */
  1067.  
  1068. /* number of bits in ULONG. Note: This must be at multiple of 16, and at
  1069.  * least 32 for the bitbuffer code to work (ie, it must be able to ensure
  1070.  * up to 17 bits - that's adding 16 bits when there's one bit left, or
  1071.  * adding 32 bits when there are no bits left. The code should work fine
  1072.  * for machines where ULONG >= 32 bits.
  1073.  */
  1074. #define ULONG_BITS (sizeof(ULONG)<<3)
  1075.  
  1076. #define INIT_BITSTREAM do { bitsleft = 0; bitbuf = 0; } while (0)
  1077.  
  1078. #define ENSURE_BITS(n)                            \
  1079.   while (bitsleft < (n)) {                        \
  1080.     bitbuf |= ((inpos[1]<<8)|inpos[0]) << (ULONG_BITS-16 - bitsleft);    \
  1081.     bitsleft += 16; inpos+=2;                        \
  1082.   }
  1083.  
  1084. #define PEEK_BITS(n)   (bitbuf >> (ULONG_BITS - (n)))
  1085. #define REMOVE_BITS(n) ((bitbuf <<= (n)), (bitsleft -= (n)))
  1086.  
  1087. #define READ_BITS(v,n) do {                        \
  1088.   ENSURE_BITS(n);                            \
  1089.   (v) = PEEK_BITS(n);                            \
  1090.   REMOVE_BITS(n);                            \
  1091.   /*D(("getbits(%ld)=%ld\n",n,(v)))*/                    \
  1092. } while (0)
  1093.  
  1094.  
  1095. /* Huffman macros */
  1096.  
  1097. #define TABLEBITS(tbl)   (LZX_##tbl##_TABLEBITS)
  1098. #define MAXSYMBOLS(tbl)  (LZX_##tbl##_MAXSYMBOLS)
  1099. #define SYMTABLE(tbl)    (LZX(tbl##_table))
  1100. #define LENTABLE(tbl)    (LZX(tbl##_len))
  1101.  
  1102. /* BUILD_TABLE(tablename) builds a huffman lookup table from code lengths.
  1103.  * In reality, it just calls make_decode_table() with the appropriate
  1104.  * values - they're all fixed by some #defines anyway, so there's no point
  1105.  * writing each call out in full by hand.
  1106.  */
  1107. #define BUILD_TABLE(tbl)                        \
  1108.   if (make_decode_table(                        \
  1109.     MAXSYMBOLS(tbl), TABLEBITS(tbl), LENTABLE(tbl), SYMTABLE(tbl)    \
  1110.   )) { D(("LZX: table failure\n")) return XADERR_ILLEGALDATA; }
  1111.  
  1112.  
  1113. /* READ_HUFFSYM(tablename, var) decodes one huffman symbol from the
  1114.  * bitstream using the stated table and puts it in var.
  1115.  */
  1116. #define READ_HUFFSYM(tbl,var) do {                    \
  1117.   ENSURE_BITS(16);                            \
  1118.   hufftbl = SYMTABLE(tbl);                        \
  1119.   if ((i = hufftbl[PEEK_BITS(TABLEBITS(tbl))]) >= MAXSYMBOLS(tbl)) {    \
  1120.     j = 1 << (ULONG_BITS - TABLEBITS(tbl));                \
  1121.     do {                                \
  1122.       j >>= 1; i <<= 1; i |= (bitbuf & j) ? 1 : 0;            \
  1123.       if (!j) return XADERR_ILLEGALDATA;                \
  1124.     } while ((i = hufftbl[i]) >= MAXSYMBOLS(tbl));            \
  1125.   }                                    \
  1126.   j = LENTABLE(tbl)[(var) = i];                        \
  1127.   REMOVE_BITS(j);                            \
  1128. } while (0)
  1129.  
  1130.  
  1131. /* READ_LENGTHS(tablename, first, last) reads in code lengths for symbols
  1132.  * first to last in the given table. The code lengths are stored in their
  1133.  * own special LZX way. Note that we pass in an lzx_bits structure to
  1134.  * get the bitstream state between the function and the caller - this has
  1135.  * to be initialised before using READ_LENGTHS, and retrieved again before
  1136.  * the bit macros are next used.
  1137.  */
  1138. #define READ_LENGTHS(tbl,first,last) \
  1139.   if (lzx_read_lens(cabstate, LENTABLE(tbl), (first), (last), &lb)) \
  1140.     return XADERR_ILLEGALDATA;
  1141.  
  1142. struct lzx_bits {
  1143.   ULONG bb;
  1144.   int bl;
  1145.   UBYTE *ip;
  1146. };
  1147.  
  1148.  
  1149. /* make_decode_table(nsyms, nbits, length[], table[])
  1150.  *
  1151.  * This function was coded by David Tritscher. It builds a fast huffman
  1152.  * decoding table out of just a canonical huffman code lengths table.
  1153.  *
  1154.  * nsyms  = total number of symbols in this huffman tree.
  1155.  * nbits  = any symbols with a code length of nbits or less can be decoded
  1156.  *          in one lookup of the table.
  1157.  * length = A table to get code lengths from [0 to syms-1]
  1158.  * table  = The table to fill up with decoded symbols and pointers.
  1159.  *
  1160.  * Returns 0 for OK or 1 for error
  1161.  */
  1162. int make_decode_table(int nsyms, int nbits, UBYTE *length, UWORD *table) {
  1163.   register UWORD sym;
  1164.   register ULONG leaf;
  1165.   register UBYTE bit_num = 1;
  1166.   ULONG fill;
  1167.   ULONG pos         = 0; /* the current position in the decode table */
  1168.   ULONG table_mask  = 1 << nbits;
  1169.   ULONG bit_mask    = table_mask >> 1; /* don't do 0 length codes */
  1170.   ULONG next_symbol = bit_mask; /* base of allocation for long codes */
  1171.  
  1172.   /* fill entries for codes short enough for a direct mapping */
  1173.   while (bit_num <= nbits) {
  1174.     for (sym = 0; sym < nsyms; sym++) {
  1175.       if (length[sym] == bit_num) {
  1176.         leaf = pos;
  1177.  
  1178.         if((pos += bit_mask) > table_mask) return 1; /* table overrun */
  1179.  
  1180.         /* fill all possible lookups of this symbol with the symbol itself */
  1181.         fill = bit_mask;
  1182.         while (fill-- > 0) table[leaf++] = sym;
  1183.       }
  1184.     }
  1185.     bit_mask >>= 1;
  1186.     bit_num++;
  1187.   }
  1188.  
  1189.   /* if there are any codes longer than nbits */
  1190.   if (pos != table_mask) {
  1191.     /* clear the remainder of the table */
  1192.     for (sym = pos; sym < table_mask; sym++) table[sym] = 0;
  1193.  
  1194.     /* give ourselves room for codes to grow by up to 16 more bits */
  1195.     pos <<= 16;
  1196.     table_mask <<= 16;
  1197.     bit_mask = 1 << 15;
  1198.  
  1199.     while (bit_num <= 16) {
  1200.       for (sym = 0; sym < nsyms; sym++) {
  1201.         if (length[sym] == bit_num) {
  1202.           leaf = pos >> 16;
  1203.           for (fill = 0; fill < bit_num - nbits; fill++) {
  1204.             /* if this path hasn't been taken yet, 'allocate' two entries */
  1205.             if (table[leaf] == 0) {
  1206.               table[(next_symbol << 1)] = 0;
  1207.               table[(next_symbol << 1) + 1] = 0;
  1208.               table[leaf] = next_symbol++;
  1209.             }
  1210.             /* follow the path and select either left or right for next bit */
  1211.             leaf = table[leaf] << 1;
  1212.             if ((pos >> (15-fill)) & 1) leaf++;
  1213.           }
  1214.           table[leaf] = sym;
  1215.  
  1216.           if ((pos += bit_mask) > table_mask) return 1; /* table overflow */
  1217.         }
  1218.       }
  1219.       bit_mask >>= 1;
  1220.       bit_num++;
  1221.     }
  1222.   }
  1223.  
  1224.   /* full table? */
  1225.   if (pos == table_mask) return 0;
  1226.  
  1227.   /* either erroneous table, or all elements are 0 - let's find out. */
  1228.   for (sym = 0; sym < nsyms; sym++) if (length[sym]) return 1;
  1229.   return 0;
  1230. }
  1231.  
  1232.  
  1233. int lzx_read_lens(CABSTATE, UBYTE *lens, int f, int l, struct lzx_bits *lb) {
  1234.   ULONG i,j, x,y;
  1235.   int z;
  1236.  
  1237.   register ULONG bitbuf = lb->bb;
  1238.   register int bitsleft = lb->bl;
  1239.   UBYTE *inpos = lb->ip;
  1240.   UWORD *hufftbl;
  1241.   
  1242.   for (x = 0; x < 20; x++) {
  1243.     READ_BITS(y, 4);
  1244.     LENTABLE(PRETREE)[x] = y;
  1245.   }
  1246.   BUILD_TABLE(PRETREE);
  1247.  
  1248.   for (x = f; x < l; ) {
  1249.     READ_HUFFSYM(PRETREE, z);
  1250.  
  1251.     if (z == 17) {
  1252.       READ_BITS(y, 4); y += 4;
  1253.       while (y--) lens[x++] = 0;
  1254.     }
  1255.     else if (z == 18) {
  1256.       READ_BITS(y, 5); y += 20;
  1257.       while (y--) lens[x++] = 0;
  1258.     }
  1259.     else if (z == 19) {
  1260.       READ_BITS(y, 1); y += 4;
  1261.       READ_HUFFSYM(PRETREE, z);
  1262.       z = lens[x] - z; if (z < 0) z += 17;
  1263.       while (y--) lens[x++] = z;
  1264.     }
  1265.     else {
  1266.       z = lens[x] - z; if (z < 0) z += 17;
  1267.       lens[x++] = z;
  1268.     }
  1269.   }
  1270.  
  1271.   lb->bb = bitbuf;
  1272.   lb->bl = bitsleft;
  1273.   lb->ip = inpos;
  1274.  
  1275.   /*for (x = f; x < l; x++) D(("length[%ld]=%ld\n", x, lens[x]))*/
  1276.  
  1277.   return 0;
  1278. }
  1279.  
  1280.  
  1281. LONG CAB_LZXdecompress(CABSTATE, int inlen, int outlen) {
  1282.   struct xadMasterBase *xadMasterBase = CAB(xad);
  1283.   UBYTE *inpos  = CAB(inbuf);
  1284.   UBYTE *endinp = inpos + inlen;
  1285.   UBYTE *window = LZX(window);
  1286.   UBYTE *runsrc, *rundest;
  1287.   UWORD *hufftbl; /* used in READ_HUFFSYM macro as chosen decoding table */
  1288.  
  1289.   ULONG window_posn = LZX(window_posn);
  1290.   ULONG window_size = LZX(window_size);
  1291.   ULONG R0 = LZX(R0);
  1292.   ULONG R1 = LZX(R1);
  1293.   ULONG R2 = LZX(R2);
  1294.  
  1295.   register ULONG bitbuf;
  1296.   register int bitsleft;
  1297.   ULONG match_offset, i,j,k; /* ijk used in READ_HUFFSYM macro */
  1298.   struct lzx_bits lb; /* used in READ_LENGTHS macro */
  1299.  
  1300.   int togo = outlen, this_run, main_element, aligned_bits;
  1301.   int match_length, length_footer, extra, verbatim_bits;
  1302.  
  1303.   INIT_BITSTREAM;
  1304.  
  1305.   /* read header if necessary */
  1306.   if (!LZX(header_read)) {
  1307.     i = j = 0;
  1308.     READ_BITS(k, 1); if (k) { READ_BITS(i,16); READ_BITS(j,16); }
  1309.     LZX(intel_filesize) = (i << 16) | j; /* or 0 if not encoded */
  1310.     LZX(header_read) = 1;
  1311.   }
  1312.  
  1313.   /* main decoding loop */
  1314.   while (togo > 0) {
  1315.     D(("LZX: top of loop, %ld togo\n", togo))
  1316.  
  1317.     /* last block finished, new block expected */
  1318.     if (LZX(block_remaining) == 0) {
  1319.       if (LZX(block_type) == LZX_BLOCKTYPE_UNCOMPRESSED) {
  1320.         if (LZX(block_length) & 1) inpos++; /* realign bitstream to word */
  1321.         INIT_BITSTREAM;
  1322.         D(("LZX: aligning after previous uncompressed block\n"))
  1323.       }
  1324.  
  1325.       READ_BITS(LZX(block_type), 3);
  1326.       READ_BITS(i, 16);
  1327.       READ_BITS(j, 8);
  1328.       LZX(block_remaining) = LZX(block_length) = (i << 8) | j;
  1329.  
  1330.       D(("LZX: new %ld block len=%ld\n", LZX(block_type), LZX(block_length)))
  1331.  
  1332.       switch (LZX(block_type)) {
  1333.       case LZX_BLOCKTYPE_ALIGNED:
  1334.         for (i = 0; i < 8; i++) { READ_BITS(j, 3); LENTABLE(ALIGNED)[i] = j; }
  1335.         BUILD_TABLE(ALIGNED);
  1336.         /* rest of aligned header is same as verbatim */
  1337.  
  1338.       case LZX_BLOCKTYPE_VERBATIM:
  1339.         /* set up a pass-in structure with bitstream state for READ_LENGTHS */
  1340.         lb.bb = bitbuf; lb.bl = bitsleft; lb.ip = inpos;
  1341.  
  1342.         READ_LENGTHS(MAINTREE, 0, 256);
  1343.         READ_LENGTHS(MAINTREE, 256, LZX(main_elements));
  1344.         BUILD_TABLE(MAINTREE);
  1345.         if (LENTABLE(MAINTREE)[0xE8] != 0) LZX(intel_started) = 1;
  1346.  
  1347.         READ_LENGTHS(LENGTH, 0, LZX_NUM_SECONDARY_LENGTHS);
  1348.         BUILD_TABLE(LENGTH);
  1349.  
  1350.         /* retrieve the bitstream state from the readlens structure */
  1351.         bitbuf = lb.bb; bitsleft = lb.bl; inpos = lb.ip;
  1352.  
  1353.         break;
  1354.  
  1355.       case LZX_BLOCKTYPE_UNCOMPRESSED:
  1356.         LZX(intel_started) = 1; /* because we can't assume otherwise */
  1357.         ENSURE_BITS(16); /* get up to 16 pad bits into the buffer */
  1358.         if (bitsleft > 16) inpos -= 2; /* and align the bitstream! */
  1359.         LZX(R0)=inpos[0]|(inpos[1]<<8)|(inpos[2]<<16)|(inpos[3]<<24);inpos+=4;
  1360.         LZX(R1)=inpos[0]|(inpos[1]<<8)|(inpos[2]<<16)|(inpos[3]<<24);inpos+=4;
  1361.         LZX(R2)=inpos[0]|(inpos[1]<<8)|(inpos[2]<<16)|(inpos[3]<<24);inpos+=4;
  1362.         D(("LZX: uncomp header; Rx=%ld/%ld/%ld\n",LZX(R0),LZX(R1),LZX(R2)))
  1363.         break;
  1364.  
  1365.       default:
  1366.         return XADERR_ILLEGALDATA;
  1367.       }
  1368.       D(("LZX: block header read OK\n"))
  1369.     }
  1370.  
  1371.     if (inpos > endinp) return XADERR_ILLEGALDATA;
  1372.  
  1373.     while ((this_run = LZX(block_remaining)) > 0 && togo > 0) {
  1374.       D(("LZX: block remaining = %ld, togo = %ld\n", this_run, togo))
  1375.       if (this_run > togo) this_run = togo;
  1376.       togo -= this_run;
  1377.       LZX(block_remaining) -= this_run;
  1378.  
  1379.       /* apply 2^x-1 mask */
  1380.       window_posn &= window_size - 1;
  1381.       /* runs can't straddle the window wraparound */
  1382.       if ((window_posn + this_run) > window_size)
  1383.         return XADERR_DATAFORMAT;
  1384.  
  1385.       switch (LZX(block_type)) {
  1386.  
  1387.       case LZX_BLOCKTYPE_VERBATIM:
  1388.         while (this_run > 0) {
  1389.           READ_HUFFSYM(MAINTREE, main_element);
  1390.           /*D(("%ld\n",main_element))*/
  1391.           if (main_element < LZX_NUM_CHARS) {
  1392.             /* literal: 0 to LZX_NUM_CHARS-1 */
  1393.             window[window_posn++] = main_element;
  1394.             this_run--;
  1395.           }
  1396.           else {
  1397.             /* match: LZX_NUM_CHARS + ((slot<<3) | length_header (3 bits)) */
  1398.             main_element -= LZX_NUM_CHARS;
  1399.   
  1400.             match_length = main_element & LZX_NUM_PRIMARY_LENGTHS;
  1401.             if (match_length == LZX_NUM_PRIMARY_LENGTHS) {
  1402.               READ_HUFFSYM(LENGTH, length_footer);
  1403.               match_length += length_footer;
  1404.             }
  1405.             match_length += LZX_MIN_MATCH;
  1406.   
  1407.             match_offset = main_element >> 3;
  1408.   
  1409.             if (match_offset > 2) {
  1410.               /* not repeated offset */
  1411.               if (match_offset != 3) {
  1412.                 extra = extra_bits[match_offset];
  1413.                 READ_BITS(verbatim_bits, extra);
  1414.                 match_offset = position_base[match_offset] - 2 + verbatim_bits;
  1415.               }
  1416.               else {
  1417.                 match_offset = 1;
  1418.               }
  1419.   
  1420.               /* update repeated offset LRU queue */
  1421.               R2 = R1; R1 = R0; R0 = match_offset;
  1422.             }
  1423.             else if (match_offset == 0) {
  1424.               match_offset = R0;
  1425.             }
  1426.             else if (match_offset == 1) {
  1427.               match_offset = R1;
  1428.               R1 = R0; R0 = match_offset;
  1429.             }
  1430.             else /* match_offset == 2 */ {
  1431.               match_offset = R2;
  1432.               R2 = R0; R0 = match_offset;
  1433.             }
  1434.  
  1435.             /*D(("%ld,%ld\n",match_length,match_offset))*/
  1436.             rundest = window + window_posn;
  1437.             runsrc  = rundest - match_offset;
  1438.             window_posn += match_length;
  1439.             this_run -= match_length;
  1440.  
  1441.             /* copy any wrapped around source data */
  1442.             while ((runsrc < window) && (match_length-- > 0)) {
  1443.              *rundest++ = *(runsrc + window_size); runsrc++;
  1444.             }
  1445.             /* copy match data - no worries about destination wraps */
  1446.             while (match_length-- > 0) *rundest++ = *runsrc++;
  1447.  
  1448.           }
  1449.         }
  1450.         break;
  1451.  
  1452.       case LZX_BLOCKTYPE_ALIGNED:
  1453.         while (this_run > 0) {
  1454.           READ_HUFFSYM(MAINTREE, main_element);
  1455.           /*D(("%ld\n",main_element))*/
  1456.   
  1457.           if (main_element < LZX_NUM_CHARS) {
  1458.             /* literal: 0 to LZX_NUM_CHARS-1 */
  1459.             window[window_posn++] = main_element;
  1460.             this_run--;
  1461.           }
  1462.           else {
  1463.             /* match: LZX_NUM_CHARS + ((slot<<3) | length_header (3 bits)) */
  1464.             main_element -= LZX_NUM_CHARS;
  1465.   
  1466.             match_length = main_element & LZX_NUM_PRIMARY_LENGTHS;
  1467.             if (match_length == LZX_NUM_PRIMARY_LENGTHS) {
  1468.               READ_HUFFSYM(LENGTH, length_footer);
  1469.               match_length += length_footer;
  1470.             }
  1471.             match_length += LZX_MIN_MATCH;
  1472.   
  1473.             match_offset = main_element >> 3;
  1474.   
  1475.             if (match_offset > 2) {
  1476.               /* not repeated offset */
  1477.               extra = extra_bits[match_offset];
  1478.               match_offset = position_base[match_offset] - 2;
  1479.               if (extra > 3) {
  1480.                 /* verbatim and aligned bits */
  1481.                 extra -= 3;
  1482.                 READ_BITS(verbatim_bits, extra);
  1483.                 match_offset += (verbatim_bits << 3);
  1484.                 READ_HUFFSYM(ALIGNED, aligned_bits);
  1485.                 match_offset += aligned_bits;
  1486.               }
  1487.               else if (extra == 3) {
  1488.                 /* aligned bits only */
  1489.                 READ_HUFFSYM(ALIGNED, aligned_bits);
  1490.                 match_offset += aligned_bits;
  1491.               }
  1492.               else if (extra > 0) { /* extra==1, extra==2 */
  1493.                 /* verbatim bits only */
  1494.                 READ_BITS(verbatim_bits, extra);
  1495.                 match_offset += verbatim_bits;
  1496.               }
  1497.               else /* extra == 0 */ {
  1498.                 /* ??? */
  1499.                 match_offset = 1;
  1500.               }
  1501.   
  1502.               /* update repeated offset LRU queue */
  1503.               R2 = R1; R1 = R0; R0 = match_offset;
  1504.             }
  1505.             else if (match_offset == 0) {
  1506.               match_offset = R0;
  1507.             }
  1508.             else if (match_offset == 1) {
  1509.               match_offset = R1;
  1510.               R1 = R0; R0 = match_offset;
  1511.             }
  1512.             else /* match_offset == 2 */ {
  1513.               match_offset = R2;
  1514.               R2 = R0; R0 = match_offset;
  1515.             }
  1516.  
  1517.             /*D(("%ld,%ld\n",match_length,match_offset))*/
  1518.             rundest = window + window_posn;
  1519.             runsrc  = rundest - match_offset;
  1520.             window_posn += match_length;
  1521.             this_run -= match_length;
  1522.  
  1523.             /* copy any wrapped around source data */
  1524.             while ((runsrc < window) && (match_length-- > 0)) {
  1525.              *rundest++ = *(runsrc + window_size); runsrc++;
  1526.             }
  1527.             /* copy match data - no worries about destination wraps */
  1528.             while (match_length-- > 0) *rundest++ = *runsrc++;
  1529.  
  1530.           }
  1531.         }
  1532.         break;
  1533.  
  1534.       case LZX_BLOCKTYPE_UNCOMPRESSED:
  1535.         if ((inpos + this_run) > endinp) return XADERR_ILLEGALDATA;
  1536.         xadCopyMem(inpos, window + window_posn, this_run);
  1537.         inpos += this_run; window_posn += this_run;
  1538.         break;
  1539.  
  1540.       default:
  1541.         return XADERR_ILLEGALDATA; /* might as well */
  1542.       }
  1543.  
  1544.     }
  1545.   }
  1546.  
  1547.   if (togo != 0) return XADERR_ILLEGALDATA;
  1548.   xadCopyMem(window + ((window_posn == 0) ? window_size : window_posn) -
  1549.     outlen, CAB(outbuf), outlen);
  1550.  
  1551.   LZX(window_posn) = window_posn;
  1552.   LZX(R0) = R0;
  1553.   LZX(R1) = R1;
  1554.   LZX(R2) = R2;
  1555.  
  1556.   /* intel decoding */
  1557.   if ((LZX(frames_read)++ < 32768) && LZX(intel_filesize) != 0) {
  1558.     if (outlen <= 6 || !LZX(intel_started)) {
  1559.       LZX(intel_curpos) += outlen;
  1560.     }
  1561.     else {
  1562.       UBYTE *data    = CAB(outbuf);
  1563.       UBYTE *dataend = data + outlen - 6;
  1564.       LONG curpos    = LZX(intel_curpos);
  1565.       LONG filesize  = LZX(intel_filesize);
  1566.       LONG abs_off, rel_off;
  1567.  
  1568.       LZX(intel_curpos) = curpos + outlen;
  1569.  
  1570.       while (data < dataend) {
  1571.         if (*data++ != 0xE8) { curpos++; continue; }
  1572.         abs_off = data[0] | (data[1]<<8) | (data[2]<<16) | (data[3]<<24);
  1573.         if ((abs_off >= -curpos) && (abs_off < filesize)) {
  1574.           rel_off = (abs_off >= 0) ? abs_off - curpos : abs_off + filesize;
  1575.           data[0] = (UBYTE) rel_off;
  1576.           data[1] = (UBYTE) (rel_off >> 8);
  1577.           data[2] = (UBYTE) (rel_off >> 16);
  1578.           data[3] = (UBYTE) (rel_off >> 24);
  1579.           /*D(("LZX: E8 abs=%08lx rel=%08lx\n",abs_off,rel_off))*/
  1580.         }
  1581.         data += 4;
  1582.         curpos += 5;
  1583.       }
  1584.     }
  1585.   }
  1586.   return XADERR_OK;
  1587. }
  1588.  
  1589.  
  1590. /*--------------------------------------------------------------------------*/
  1591. /* CAB RecogData/GetInfo code */
  1592.  
  1593. /* UTF translates two-byte unicode characters into 1, 2 or 3 bytes.
  1594.  * %000000000xxxxxxx (0x0000 - 0x007F) -> %0xxxxxxx
  1595.  * %00000xxxxxyyyyyy (0x0080 - 0x07FF) -> %110xxxxx %10yyyyyy
  1596.  * %xxxxyyyyyyzzzzzz (0x0800 - 0xFFFF) -> %1110xxxx %10yyyyyy %10zzzzzz
  1597.  *
  1598.  * Therefore, the inverse is as follows:
  1599.  * First char:
  1600.  *  0x00 - 0x7F = one byte char
  1601.  *  0x80 - 0xBF = invalid
  1602.  *  0xC0 - 0xDF = 2 byte char (next char only 0x80-0xBF is valid)
  1603.  *  0xE0 - 0xEF = 3 byte char (next 2 chars only 0x80-0xBF is valid)
  1604.  *  0xF0 - 0xFF = invalid
  1605.  */
  1606. /* translates a UTF string into an ISO latin1 string, returns success */
  1607. int CAB_convertUTF(unsigned char *in) {
  1608.   unsigned char c, *out = in, *end = in + strlen(in) + 1;
  1609.   unsigned int x;
  1610.  
  1611.   do {
  1612.     /* read unicode character */
  1613.     if ((c = *in++) < 0x80) x = c;
  1614.     else {
  1615.       if (c < 0xC0) return 0;
  1616.       else if (c < 0xE0) {
  1617.         x = (c & 0x1F) << 6;
  1618.         if ((c = *in++) < 0x80 || c > 0xBF) return 0; else x |= (c & 0x3F);
  1619.       }
  1620.       else if (c < 0xF0) {
  1621.         x = (c & 0xF) << 12;
  1622.         if ((c = *in++) < 0x80 || c > 0xBF) return 0; else x |= (c & 0x3F)<<6;
  1623.         if ((c = *in++) < 0x80 || c > 0xBF) return 0; else x |= (c & 0x3F);
  1624.       }
  1625.       else return 0;
  1626.     }
  1627.  
  1628.     /* terrible unicode -> ISO latin1 conversion */
  1629.     if (x > 255) x = '_';
  1630.  
  1631.     if (in > end) return 0; /* just in case */
  1632.   } while (*out++ = (unsigned char) x);
  1633.   return 1;
  1634. }
  1635.  
  1636. static const STRPTR CAB_typenames[] = {
  1637.   "stored", "MSZIP", "Quantum", "LZX"
  1638. };
  1639.  
  1640. ASM(BOOL) CAB_RecogData(REG(d0, ULONG size), REG(a0, STRPTR d), XADBASE) {
  1641.   return (BOOL) ((d[0]=='M' && d[1]=='S' && d[2]=='C' && d[3]=='F') ? 1 : 0);
  1642. }
  1643.  
  1644. ASM(LONG) SAVEDS CAB_GetInfo(REG(a0, struct xadArchiveInfo *ai), XADBASE) {
  1645.   UBYTE buf[cfhead_SIZEOF];   /* buffer for reading in structures  */
  1646.   UBYTE namebuf[CAB_NAMEMAX]; /* buffer for file paths             */
  1647.   UBYTE *namep, c;            /* for char loops on namebuf         */
  1648.  
  1649.   ULONG base_offset;  /* the file offset of the start of this cabinet        */
  1650.   ULONG files_offset; /* the file offset of the first CFFILE in this cabinet */
  1651.   ULONG end_offset;   /* the file offset of the end of this cabinet          */
  1652.  
  1653.   UWORD num_folders;  /* the number of CFFOLDERs in this cabinet */
  1654.   UWORD num_files;    /* the number of CFFILEs in this cabinet   */
  1655.  
  1656.   UWORD header_res;   /* the empty space reserved in the CFHEADER */
  1657.   UBYTE folder_res;   /* the empty space reserved in each CFFOLDER */
  1658.   UBYTE data_res;     /* the empty space reserved in CFDATA */
  1659.  
  1660.   int i, x, curfile=1, curvol=-1, mergeok;
  1661.  
  1662.   struct CABfolder *firstfol;       /* first folder in this cabinet */
  1663.   struct CABfolder *lastfol = NULL; /* last folder in this cabinet */
  1664.   struct CABfolder *predfol;        /* last folder in previous cabinet */
  1665.  
  1666.   struct CABfolder *linkfol = NULL, *fol; /* folder addition loop */
  1667.   struct xadFileInfo *link = NULL,  *fi;  /* file addition loop */
  1668.  
  1669.   LONG err = XADERR_OK;
  1670.  
  1671.   struct TagItem filetags[]  = {
  1672.     { XAD_OBJNAMESIZE, 0 },
  1673.     { TAG_DONE, 0 }
  1674.   };
  1675.  
  1676.   struct TagItem datetags[] = {
  1677.     { XAD_DATEMSDOS, 0 },
  1678.     { XAD_GETDATEXADDATE, 0 },
  1679.     { TAG_DONE, 0 }
  1680.   };
  1681.  
  1682.   struct TagItem prottags[] = {
  1683.     { XAD_PROTMSDOS, 0 },
  1684.     { XAD_GETPROTAMIGA, 0 },
  1685.     { TAG_DONE, 0 }
  1686.   };
  1687.  
  1688.   /* attach state information to archive */
  1689.   ALLOC(APTR, ai->xai_PrivateClient, sizeof(struct CABstate));
  1690.  
  1691.   while (1) {
  1692.     /* the below if statement is the natural exit point of this loop */
  1693.     if (ai->xai_MultiVolume) {
  1694.       ULONG pos = ai->xai_InPos, next = ai->xai_MultiVolume[++curvol];
  1695.       D(("CAB: top wanted=%ld actual=%ld\n",next,pos))
  1696.       /* files end when the 'next file' offset is 0 - except, of course
  1697.        * for the very first iteration of this loop, because the first
  1698.        * file's offset is also 0
  1699.        */
  1700.       if (!next && curvol) goto exit_handler; /* end of files */
  1701.       if (pos < next) SKIP(next - pos);       /* skip to next file */
  1702.       if (pos > next) ERROR(ILLEGALDATA);     /* overrun error */
  1703.     }
  1704.     else {
  1705.       /* singlefile exit point - we shouldn't do more than one loop. */
  1706.       if (++curvol) goto exit_handler;
  1707.     }
  1708.  
  1709.     base_offset = ai->xai_InPos;
  1710.  
  1711.     /* ------------- PROCESS CFHEADER -------------- */
  1712.  
  1713.     READ(&buf, cfhead_SIZEOF);
  1714.     files_offset = GETLONG(cfhead_FileOffset)  + base_offset;
  1715.     end_offset   = GETLONG(cfhead_CabinetSize) + base_offset;
  1716.  
  1717.     if ((buf[0]!='M' || buf[1]!='S' || buf[2]!='C' || buf[3]!='F')
  1718.     || ((num_folders = GETWORD(cfhead_NumFolders)) == 0)
  1719.     || ((num_files   = GETWORD(cfhead_NumFiles))   == 0))
  1720.       ERROR(ILLEGALDATA);
  1721.  
  1722.     if (GETBYTE(cfhead_MajorVersion) > 1
  1723.     ||  GETBYTE(cfhead_MinorVersion) > 3) ERROR(DATAFORMAT);
  1724.  
  1725.     /* read 'reserve' part of header if present and skip reserved header */
  1726.     if ((x = GETWORD(cfhead_Flags)) & cfheadRESERVE_PRESENT) {
  1727.       READ(&buf, cfheadext_SIZEOF);
  1728.       header_res = GETWORD(cfheadext_HeaderReserved);
  1729.       folder_res = GETBYTE(cfheadext_FolderReserved);
  1730.       data_res   = GETBYTE(cfheadext_DataReserved);
  1731.  
  1732.       SKIP(header_res);
  1733.       if (header_res > 60000) TAINT("header reserved > 60000");
  1734.     }
  1735.     else {
  1736.       folder_res = data_res = 0;
  1737.     }
  1738.  
  1739.     /* skip next and previous cabinet filenames/disknames if present */
  1740.     i = ((x & cfheadPREV_CABINET) ? 2:0) + ((x & cfheadNEXT_CABINET) ? 2:0);
  1741.     while (i--) {
  1742.       int len = 0;
  1743.       do { READ(&buf, 1); len++; } while (*buf);
  1744.       if (len > 256) TAINT("nameskip > 256");
  1745.     }
  1746.  
  1747.  
  1748.     /* ------------- PROCESS CFFOLDERs ------------- */
  1749.  
  1750.     firstfol = NULL;
  1751.     predfol = lastfol;
  1752.  
  1753.     for (i = 0; i < num_folders; i++) {
  1754.       READ(&buf, cffold_SIZEOF);
  1755.  
  1756.       D(("CAB: folder offset=%ld comptype=0x%lx\n",
  1757.         GETLONG(cffold_DataOffset)+base_offset, GETWORD(cffold_CompType)
  1758.       ))
  1759.  
  1760.       SKIP(folder_res);
  1761.  
  1762.       ALLOC(struct CABfolder *, fol, sizeof(struct CABfolder));
  1763.       fol->offsets[0]  = GETLONG(cffold_DataOffset) + base_offset;
  1764.       fol->comp_type   = GETWORD(cffold_CompType);
  1765.       fol->data_res[0] = data_res;
  1766.       fol->num_splits  = 0;
  1767.  
  1768.       if (!firstfol) firstfol = fol;
  1769.       lastfol = fol;
  1770.  
  1771.       /* link folder into folders list */
  1772.       if (linkfol) linkfol->next=fol;
  1773.       else ((struct CABstate *) ai->xai_PrivateClient)->folders = fol;
  1774.       linkfol = fol;
  1775.     }
  1776.  
  1777.     /* firstfol = first folder in this cabinet */
  1778.     /* lastfol  = last folder in this cabinet */
  1779.     /* predfol  = last folder in previous cabinet (or NULL if first cabinet) */
  1780.  
  1781.     /* assume that this cabinet's split files are OK to merge */
  1782.     mergeok = 1;
  1783.  
  1784.     /* ------------- PROCESS CFFILEs ------------- */
  1785.     if (ai->xai_InPos != files_offset) TAINT("not at file offset");
  1786.  
  1787.     for (i = 0; i < num_files; i++) {
  1788.       READ(&buf, cffile_SIZEOF);
  1789.  
  1790.       /* read filename */
  1791.       namep = namebuf;
  1792.       do {
  1793.         if ((namep - namebuf) > CAB_NAMEMAX) ERROR(NOMEMORY);
  1794.         READ(namep, 1);
  1795.       } while (*namep++);
  1796.  
  1797.       /* convert filename */
  1798.       if ((x = GETWORD(cffile_Attribs) & cffileUTFNAME)
  1799.       && !CAB_convertUTF(namebuf)) TAINT("bad UTF name");
  1800.  
  1801.       for (namep = namebuf; c = *namep; namep++) {
  1802.         if (c == '/')  *namep = '\\';
  1803.         if (c == '\\') *namep = '/';
  1804.         if (!x && c > 127) *namep = '_';
  1805.       }
  1806.  
  1807.       D(("CAB: file size=%ld offset=%ld index=0x%lx name=«%s»\n",
  1808.         GETLONG(cffile_UncompressedSize), GETLONG(cffile_FolderOffset),
  1809.         GETWORD(cffile_FolderIndex), namebuf
  1810.       ))
  1811.  
  1812.       /* file information entry */
  1813.       filetags[0].ti_Data = (x = strlen((char *) namebuf) + 1);
  1814.       ALLOCOBJ(struct xadFileInfo *, fi, XADOBJ_FILEINFO, filetags);
  1815.  
  1816.       fi->xfi_EntryNumber = curfile++;
  1817.       fi->xfi_Size        = GETLONG(cffile_UncompressedSize);
  1818.       fi->xfi_DataPos     = GETLONG(cffile_FolderOffset);
  1819.       xadCopyMem(namebuf, fi->xfi_FileName, x);
  1820.  
  1821.       prottags[0].ti_Data = GETWORD(cffile_Attribs);
  1822.       prottags[1].ti_Data = (ULONG) &fi->xfi_Protection;
  1823.       xadConvertProtectionA(prottags);
  1824.  
  1825.       datetags[0].ti_Data = (GETWORD(cffile_Date)<<16)|GETWORD(cffile_Time);
  1826.       datetags[1].ti_Data = (ULONG) &fi->xfi_Date;
  1827.       xadConvertDatesA(datetags);
  1828.  
  1829.       /* which folder is this file in? */
  1830.       x = GETWORD(cffile_FolderIndex);
  1831.       if (x < num_folders) {
  1832.         for (fol = firstfol; x--; fol=fol->next);
  1833.         fi->xfi_PrivateInfo = (APTR) fol;
  1834.       }
  1835.       else {
  1836.         if (ai->xai_MultiVolume) {
  1837.           /* FOLDER MERGING */
  1838.  
  1839.           if (x == cffileCONTINUED_TO_NEXT
  1840.           || x == cffileCONTINUED_PREV_AND_NEXT) {
  1841.             D(("CAB: file merge next\n"))
  1842.             /* this file is in the next cabinet, so we don't set its folder
  1843.              * as it will be repeated with the 'prev' folder in the next
  1844.              * cabinet. also, if this file is continued prev and next, it
  1845.              * can only be a single file extending a single folder beyond
  1846.              * the cabinet size limits, the next file _has_ to start in a
  1847.              * new folder. we can test that.
  1848.              */
  1849.             if (x == cffileCONTINUED_PREV_AND_NEXT) {
  1850.               if (num_folders != 1 || num_files != 1) TAINT("prev/next");
  1851.             }
  1852.  
  1853.             if (!lastfol->contfile) lastfol->contfile = fi;
  1854.           }
  1855.  
  1856.           if (x == cffileCONTINUED_FROM_PREV
  1857.           || x == cffileCONTINUED_PREV_AND_NEXT) {
  1858.             D(("CAB: file merge prev\n"))
  1859.  
  1860.             /* if these files are to be continued in yet _another_ cabinet,
  1861.              * don't merge them in just yet
  1862.              */
  1863.             if (x == cffileCONTINUED_PREV_AND_NEXT) mergeok = 0;
  1864.  
  1865.             /* only merge once per cabinet */
  1866.             if (predfol) {
  1867.               struct xadFileInfo *cfi;
  1868.   
  1869.             /* in this case, the file states that folder 0 of this cabinet
  1870.                * is actually part of the last folder in the previous cabinet.
  1871.                * if this is true, the first 'continued' file of the last
  1872.                * folder will match the first file of this folder. Also,
  1873.                * both folders will have the same compression type.
  1874.                */
  1875.               if ((cfi = predfol->contfile)
  1876.               && (cfi->xfi_DataPos == fi->xfi_DataPos)
  1877.               && (cfi->xfi_Size == fi->xfi_Size)
  1878.               && (strcmp(cfi->xfi_FileName, fi->xfi_FileName) == 0)
  1879.               && (predfol->comp_type == firstfol->comp_type)) {
  1880.  
  1881.                 /* free the fileinfo kept for testing if last occurance */
  1882.                 if (x == cffileCONTINUED_FROM_PREV) {
  1883.                   FREE(predfol->contfile);
  1884.                   predfol->contfile = NULL;
  1885.                 }
  1886.  
  1887.                 /* increase the number of splits */
  1888.                 if ((x = ++(predfol->num_splits)) > CAB_SPLITMAX)
  1889.                   ERROR(DATAFORMAT);
  1890.  
  1891.                 /* copy information across from the merged folder */
  1892.                 predfol->offsets[x]  = firstfol->offsets[0];
  1893.                 predfol->data_res[x] = firstfol->data_res[0];
  1894.                 predfol->next        = firstfol->next;
  1895.                 predfol->contfile    = firstfol->contfile;
  1896.  
  1897.                 if (firstfol == lastfol) lastfol = linkfol = predfol;
  1898.  
  1899.                 FREE(firstfol);
  1900.                 firstfol = predfol;
  1901.                 predfol = NULL; /* don't merge again within this cabinet */
  1902.  
  1903.               }
  1904.               else {
  1905.                 /* if the merged folders are incompatible, certainly
  1906.                  * don't list the files in them
  1907.                  */
  1908.                 mergeok = 0;
  1909.               }
  1910.             }
  1911.  
  1912.             /* only add split files at their final appearance
  1913.              * and only if merging was actually possible
  1914.              */
  1915.             if (mergeok) fi->xfi_PrivateInfo = (APTR) firstfol;
  1916.           }
  1917.         }
  1918.         else {
  1919.           /* not multivolume - can't do a folder merge, therefore it either
  1920.            * IS a merge but there's no next/prev cabinet (missing data),
  1921.            * or it's an out of range folder index (corrupt data)
  1922.            */
  1923.           TAINT("folder index");
  1924.         }
  1925.       }
  1926.  
  1927.       /* if there's no folder, skip this file */
  1928.       if (!fi->xfi_PrivateInfo) {
  1929.         /* but only free it if never used again */
  1930.         if (fi != lastfol->contfile) FREE(fi);
  1931.         continue;
  1932.       }
  1933.       else {
  1934.         /* use compression mode of this file's folder as entryinfo name */
  1935.         UWORD ct = CABFILEFOL(fi)->comp_type & cffoldCOMPTYPE_MASK;
  1936.         if (ct <= cffoldCOMPTYPE_LZX) fi->xfi_EntryInfo = CAB_typenames[ct];
  1937.       }
  1938.  
  1939.       /* link file into file list */
  1940.       if (link) link->xfi_Next = fi; else ai->xai_FileInfo = fi;
  1941.       link = fi;
  1942.     }
  1943.  
  1944.  
  1945.     /* Skip looking at the CFDATA blocks. Why? Well, it requires us to read
  1946.      * and skip the entire file, and the only information we get from doing
  1947.      * that is how large each folder is. Why not just use the offsets
  1948.      * between folders to define that? It's slightly less accurate - some
  1949.      * would say more accurate because it counts the block header overhead
  1950.      * - and there will be a calculation error if the folders are not
  1951.      * defined in order of data block appearance [I haven't seen any such
  1952.      * files], but overall it's much faster
  1953.      */
  1954.     for (fol = firstfol; fol; fol=fol->next) {
  1955.       fol->comp_size =
  1956.         ((fol->next) ? fol->next->offsets[0] : end_offset) - fol->offsets[0];
  1957.     }
  1958.   }
  1959.  
  1960. exit_handler:
  1961.   /* free any continuation comparison files in use */
  1962.   fol = ((struct CABstate *) ai->xai_PrivateClient)->folders;
  1963.   for (; fol; fol=fol->next) {
  1964.     if (fol->contfile) {
  1965.       TAINT("incomplete folder merge");
  1966.       FREE(fol->contfile);
  1967.     }
  1968.   }
  1969.  
  1970.   /* fill in group crunched sizes */
  1971.   for (fi = ai->xai_FileInfo; fi; fi = fi->xfi_Next) {
  1972.     fi->xfi_Flags = XADFIF_GROUPED;
  1973.     if (!fi->xfi_Next || (CABFILEFOL(fi) != CABFILEFOL(fi->xfi_Next))) {
  1974.       fi->xfi_Flags |= XADFIF_ENDOFGROUP;
  1975.       fi->xfi_GroupCrSize = CABFILEFOL(fi)->comp_size;
  1976.     }
  1977.   }
  1978.  
  1979.   /* if tainted, add the tainted lasterror */
  1980.   if (ai->xai_Flags & XADAIF_FILECORRUPT)
  1981.     ai->xai_LastError = XADERR_ILLEGALDATA;
  1982.  
  1983.   /* if a real error, then if we have files, taint and set, otherwise quit */
  1984.   if (err) {
  1985.     if (!ai->xai_FileInfo) return err;
  1986.     ai->xai_Flags |= XADAIF_FILECORRUPT;
  1987.     ai->xai_LastError = err;
  1988.     D(("CAB: info error=%ld\n", err))
  1989.   }
  1990.   return XADERR_OK;
  1991. }
  1992.  
  1993.  
  1994.  
  1995. /*--------------------------------------------------------------------------*/
  1996. /* UnArchive / Free section */
  1997.  
  1998. LONG CAB_NONEdecompress(CABSTATE, int inlen, int outlen) {
  1999.   struct xadMasterBase *xadMasterBase = CAB(xad);
  2000.  
  2001.   if (inlen != outlen) return XADERR_ILLEGALDATA;
  2002.   xadCopyMem(CAB(inbuf), CAB(outbuf), inlen);
  2003.   return XADERR_OK;
  2004. }
  2005.  
  2006. ULONG CAB_checksum(UBYTE *data, UWORD bytes, ULONG csum) {
  2007.   int len;
  2008.   ULONG ul = 0;
  2009.  
  2010.   for (len = bytes >> 2; len--; data += 4) {
  2011.     csum ^= ((data[0]) | (data[1]<<8) | (data[2]<<16) | (data[3]<<24));
  2012.   }
  2013.  
  2014.   switch (bytes & 3) {
  2015.   case 3: ul |= *data++ << 16;
  2016.   case 2: ul |= *data++ <<  8;
  2017.   case 1: ul |= *data;
  2018.   }
  2019.   csum ^= ul;
  2020.  
  2021.   return csum;
  2022. }
  2023.  
  2024. LONG CAB_decompress(CABSTATE, ULONG bytes, int save) {
  2025.   struct xadArchiveInfo *ai = CAB(ai);
  2026.   struct xadMasterBase *xadMasterBase = CAB(xad);
  2027.  
  2028.   UBYTE buf[cfdata_SIZEOF], *data;
  2029.   UWORD inlen, len, outlen, cando;
  2030.   ULONG cksum;
  2031.   LONG err = XADERR_OK;
  2032.  
  2033.   /* here's an optimisation to prevent the re-decoding of a folder with an
  2034.    * error at some position in it. If a file or skip goes beyond the point
  2035.    * where we last got an error, then we won't bother going through it all
  2036.    * again, we'll just repeat the error.
  2037.    */
  2038.   if (CAB(current) == CAB(lastfolder)
  2039.   && (CAB(offset) + bytes) > CAB(lastoffset))
  2040.     return CAB(lasterror);
  2041.  
  2042.  
  2043.   while (bytes > 0) {
  2044.     /* cando = the max number of bytes we can do */
  2045.     cando = CAB(outlen);
  2046.     if (cando > bytes) cando = bytes;
  2047.     D(("CAB: decomp bytes=%ld cando=%ld\n", bytes, cando))
  2048.     if (cando && save) WRITE(CAB(outpos), cando); /* if cando != 0 */
  2049.     CAB(outpos) += cando;
  2050.     CAB(outlen) -= cando;
  2051.     bytes -= cando; if (!bytes) break;
  2052.  
  2053.     /* we only get here if we emptied the output buffer */
  2054.  
  2055.     /* read data header + data */
  2056.     inlen = outlen = 0;
  2057.     while (outlen == 0) {
  2058.       /* read the block header, skip the reserved part */
  2059.       READ(buf, cfdata_SIZEOF);
  2060.       SKIP(CAB(current)->data_res[CAB(split)]);
  2061.  
  2062.       /* we shouldn't get blocks over CAB_INPUTMAX in size */
  2063.       data = CAB(inbuf) + inlen;
  2064.       if ((inlen += (len = GETWORD(cfdata_CompressedSize))) > CAB_INPUTMAX)
  2065.         ERROR(INPUT);
  2066.  
  2067.       READ(data, len);
  2068.  
  2069.       /* perform checksum test on the block (if one is stored) */
  2070.       if ((cksum = GETLONG(cfdata_CheckSum)) != 0) {
  2071.         if (cksum != CAB_checksum(buf+4, 4, CAB_checksum(data, len, 0)))
  2072.           ERROR(CHECKSUM);
  2073.       }
  2074.  
  2075.       /* outlen=0 means this block was part of a split block */
  2076.       if ((outlen = GETWORD(cfdata_UncompressedSize)) == 0) {
  2077.         CAB(split)++; SEEK(CAB(current)->offsets[CAB(split)]);
  2078.       }
  2079.     }
  2080.  
  2081.     /* decompress block */
  2082.     if ((err = CAB(decompress)(cabstate, inlen, outlen))) goto exit_handler;
  2083.     CAB(outlen) = outlen;
  2084.     CAB(outpos) = CAB(outbuf);
  2085.   }
  2086.  
  2087. exit_handler:
  2088.   if (err) {
  2089.     if (err == XADERR_INPUT
  2090.     ||  err == XADERR_ILLEGALDATA
  2091.     ||  err == XADERR_DECRUNCH
  2092.     ||  err == XADERR_CHECKSUM
  2093.     ||  err == XADERR_DATAFORMAT) {
  2094.       CAB(lasterror)  = err;
  2095.       CAB(lastfolder) = CAB(current);
  2096.       CAB(lastoffset) = CAB(offset);
  2097.     }
  2098.  
  2099.     /* reset folder */
  2100.     CAB(current) = NULL;
  2101.   }
  2102.   return err;
  2103. }
  2104.  
  2105. ASM(LONG) SAVEDS CAB_UnArchive(REG(a0, struct xadArchiveInfo *ai), XADBASE) {
  2106.   struct CABstate *cabstate = (struct CABstate *) ai->xai_PrivateClient;
  2107.   struct xadFileInfo *file = ai->xai_CurFile;
  2108.   struct CABfolder *fol = CABFILEFOL(file);
  2109.   LONG err = XADERR_OK;
  2110.  
  2111.   CAB(ai)  = ai;
  2112.   CAB(xad) = xadMasterBase;
  2113.  
  2114.   /* is a change of folder needed? do we need to reset the current folder? */
  2115.   if (fol != CAB(current) || file->xfi_DataPos < CAB(offset)) {
  2116.     UWORD comptype = fol->comp_type;
  2117.  
  2118.     /* if the archiver has changed, call the old archiver's free() function */
  2119.     if (CAB(free) && CAB(current) && ((comptype & cffoldCOMPTYPE_MASK)
  2120.     != (CAB(current)->comp_type & cffoldCOMPTYPE_MASK))) CAB(free)(cabstate);
  2121.  
  2122.     switch (comptype & cffoldCOMPTYPE_MASK) {
  2123.     case cffoldCOMPTYPE_NONE:
  2124.       CAB(decompress) = CAB_NONEdecompress;
  2125.       CAB(free) = NULL;
  2126.       break;
  2127.     case cffoldCOMPTYPE_MSZIP:
  2128.       CAB(decompress) = CAB_ZIPdecompress;
  2129.       CAB(free) = NULL;
  2130.       break;
  2131.  
  2132.     case cffoldCOMPTYPE_QUANTUM:
  2133.       CAB(decompress) = CAB_QTMdecompress;
  2134.       CAB(free) = CAB_QTMfree;
  2135.       err = CAB_QTMinit(cabstate, (comptype>>4) & 0xf, (comptype>>8) & 0x1f);
  2136.       break;
  2137.  
  2138.     case cffoldCOMPTYPE_LZX:
  2139.       CAB(decompress) = CAB_LZXdecompress;
  2140.       CAB(free) = CAB_LZXfree;
  2141.       err = CAB_LZXinit(cabstate, (comptype >> 8 & 0x1f));
  2142.       break;
  2143.  
  2144.     default:
  2145.       err = XADERR_NOTSUPPORTED;
  2146.     }
  2147.     if (err) goto exit_handler;
  2148.  
  2149.     /* initialisation OK, set current folder and reset offset */
  2150.     SEEK(fol->offsets[0]);
  2151.     CAB(current) = fol;
  2152.     CAB(offset) = 0;
  2153.     CAB(outlen) = 0; /* discard existing block */
  2154.     CAB(split)  = 0;
  2155.   }
  2156.  
  2157.   if (file->xfi_DataPos > CAB(offset)) {
  2158.     D(("CAB: unarc skipping %ld bytes\n",file->xfi_DataPos-CAB(offset)))
  2159.     /* decode bytes and send them to /dev/null */
  2160.     if ((err = CAB_decompress(cabstate, file->xfi_DataPos-CAB(offset), 0)))
  2161.       return err;
  2162.     else
  2163.       CAB(offset) = file->xfi_DataPos;
  2164.   }
  2165.  
  2166.   /* decode bytes and save them */
  2167.   D(("CAB: unarc decoding %ld bytes\n",file->xfi_Size))
  2168.   if (!(err = CAB_decompress(cabstate, file->xfi_Size, 1)))
  2169.     CAB(offset) += file->xfi_Size;
  2170.  
  2171. exit_handler:
  2172.   return err;
  2173. }
  2174.  
  2175.  
  2176. ASM(void) CAB_Free(REG(a0, struct xadArchiveInfo *ai), XADBASE) {
  2177.   struct CABstate *cabstate = (struct CABstate *) ai->xai_PrivateClient;
  2178.   struct CABfolder *f, *nf;
  2179.  
  2180.   if (!cabstate) return;
  2181.   if (CAB(free)) CAB(free)(cabstate); /* call archiver's free() function */
  2182.   for (f = CAB(folders); f; f = nf) { nf = f->next; FREE(f); }
  2183.   FREE(cabstate);
  2184.   ai->xai_PrivateClient = NULL;
  2185. }
  2186.  
  2187.  
  2188. /*--------------------------------------------------------------------------*/
  2189. /* executable loader */
  2190.  
  2191. ASM(BOOL) CABEXE_RecogData(REG(d0, ULONG size), REG(a0, UBYTE *d), XADBASE) {
  2192.   if (size < 20000 || d[0] != 'M' || d[1] != 'Z') return 0;
  2193.  
  2194.   /* word aligned code signature: 817C2404 "MSCF" (found at random, sorry) */
  2195.   for (d+=8, size-=8; size >= 12; d+=2, size-=2) {
  2196.     if (d[0]==0x81 && d[1]==0x7C && d[2]==0x24 && d[3]==0x04
  2197.     &&  d[4]=='M'  && d[5]=='S'  && d[6]=='C'  && d[7]=='F')
  2198.       return 1;
  2199.  
  2200.     /* another revision: 7D817DDC "MSCF" (which might not be aligned) */
  2201.     if (d[0]==0x81 && d[1]==0x7D && d[2]==0xDC
  2202.     &&  d[3]=='M'  && d[4]=='S'  && d[5]=='C'  && d[6]=='F')
  2203.       return 1;
  2204.  
  2205.     if (d[0]==0x7D && d[1]==0x81 && d[2]==0x7D && d[3]==0xDC
  2206.     &&  d[4]=='M'  && d[5]=='S'  && d[6]=='C'  && d[7]=='F')
  2207.       return 1;
  2208.   }
  2209.   return 0;
  2210. }
  2211.  
  2212.  
  2213. #define CABEXE_START (55  * 1024) /* search from 55k (StartBTClick.exe) */
  2214. #define CABEXE_END   (150 * 1024) /* search to 150k (says dirk)         */
  2215.  
  2216. ASM(LONG) CABEXE_GetInfo(REG(a0, struct xadArchiveInfo *ai), XADBASE) {
  2217.   /* offset=0 as sentinel is OK; file has to start "MZ" to get here */
  2218.   ULONG filelen, readlen, offset = 0, i;
  2219.   UBYTE *buf, *p;
  2220.   LONG err;
  2221.  
  2222.   filelen = ai->xai_InSize;
  2223.   if ((readlen = filelen - CABEXE_START) > (CABEXE_END - CABEXE_START)) {
  2224.     readlen = CABEXE_END - CABEXE_START;
  2225.   }
  2226.  
  2227.   ALLOC(UBYTE *, buf, readlen);
  2228.   SKIP(CABEXE_START);
  2229.   READ(buf, readlen);
  2230.  
  2231.   readlen -= cfhead_SIZEOF;
  2232.   for (i=0, p=buf; i < readlen; i++, p++) {
  2233.  
  2234.     /* if we find a header */
  2235.     if (p[0]=='M' && p[1]=='S' && p[2]=='C' && p[3]=='F') {
  2236.       /* read the 'length of cab file and 'offset within cab file' */
  2237.       ULONG len  = (p[8])  | (p[9]<<8)  | (p[10]<<16) | (p[11]<<24);
  2238.       ULONG foff = (p[16]) | (p[17]<<8) | (p[18]<<16) | (p[19]<<24);
  2239.       /* if these lengths are consistent, we have a match! */
  2240.       if (len < filelen && foff < len) {
  2241.         offset = CABEXE_START + i;
  2242.         D(("CAB: exe offset=%ld\n",offset))
  2243.         goto exit_handler;
  2244.       }
  2245.     }
  2246.   }
  2247.   err = XADERR_DATAFORMAT;
  2248.  
  2249. exit_handler:
  2250.   if (buf) FREE(buf);
  2251.  
  2252.   /* if we found a match, actually look at the archive */
  2253.   if (offset != 0) {
  2254.     SEEK(offset);
  2255.     err = CAB_GetInfo(ai, xadMasterBase);
  2256.   }
  2257.   return err;
  2258. }
  2259.  
  2260.  
  2261. /*--------------------------------------------------------------------------*/
  2262.  
  2263. const struct xadClient CABEXE_Client = {
  2264.   NEXTCLIENT, XADCLIENT_VERSION, 6, CAB_VERSION, CAB_REVISION,
  2265.  
  2266.   65536, /* first 64kb should have signature */
  2267.   XADCF_FILEARCHIVER|XADCF_FREEFILEINFO|XADCF_FREESKIPINFO|XADCF_NOCHECKSIZE,
  2268.   0, "CAB MS-EXE",
  2269.  
  2270.   /* client functions */
  2271.   (BOOL (*)()) CABEXE_RecogData,
  2272.   (LONG (*)()) CABEXE_GetInfo,
  2273.   (LONG (*)()) CAB_UnArchive,
  2274.   (void (*)()) CAB_Free
  2275. };
  2276.  
  2277. const struct xadClient CAB_Client = {
  2278.   (struct xadClient *) &CABEXE_Client,
  2279.   XADCLIENT_VERSION, 6, CAB_VERSION, CAB_REVISION,
  2280.  
  2281.   14,
  2282.   XADCF_FILEARCHIVER | XADCF_FREEFILEINFO | XADCF_FREESKIPINFO,
  2283.   0, "CAB",
  2284.  
  2285.   /* client functions */
  2286.   (BOOL (*)()) CAB_RecogData,
  2287.   (LONG (*)()) CAB_GetInfo,
  2288.   (LONG (*)()) CAB_UnArchive,
  2289.   (void (*)()) CAB_Free
  2290. };
  2291.